# Acceptable Casks Some casks should not go in [homebrew/cask](https://github.com/Homebrew/homebrew-cask). But there are additional [Interesting Taps and Forks](interesting-taps-and-forks) and anyone can [start their own](taps)! ## Finding a Home For Your Cask We maintain separate Taps for different types of binaries. Our nomenclature is: * **Stable** : The latest version provided by the developer defined by them as such. * **Beta, Development, Unstable** : Subsequent versions to **stable** , yet incomplete and under development, aiming to eventually become the new **stable**. Also includes alternate versions specifically targeted at developers. * **Nightly** : Constantly up-to-date versions of the current development state. * **Legacy** : Any **stable** version that is not the most recent. * **Regional, Localized** : Any version that isn’t the US English one, when that exists. * **Trial** : Time-limited version that stops working entirely after it expires, requiring payment to lift the limitation. * **Freemium** : Gratis version that works indefinitely but with limitations that can be removed by paying. * **Fork** : An alternate version of an existing project, with a based-on but modified source and binary. * **Unofficial** : An _allegedly_ unmodified compiled binary, by a third-party, of a binary that has no existing build by the owner of the source code. * **Vendorless** : A binary distributed without an official website, like a forum posting. * **Walled** : When the download URL is both behind a login/registration form and from a host that differs from the homepage. * **Font** : Data file containing a set of glyphs, characters, or symbols, that changes typed text. * **Driver** : Software to make a hardware peripheral recognisable and usable by the system. If the software is useless without the peripheral, it’s considered a driver. ### Stable Versions Stable versions live in the main repository at [Homebrew/homebrew- cask](https://github.com/Homebrew/homebrew-cask). They should run on the latest release of macOS or the previous point release (High Sierra and Mojave as of late 2018). ### But There Is No Stable Version! When software is only available as a beta, development, or unstable version, its cask can go in the main repo. When stable versions become available, only those will be accepted as subsequent updates. ### Beta, Unstable, Development, Nightly, or Legacy Alternative versions should be submitted to [Homebrew/homebrew-cask- versions](https://github.com/Homebrew/homebrew-cask-versions). ### Regional and Localized When an App exists in more than one language or has different regional editions, [the `language` stanza should be used to switch between languages or regions](cask-cookbook#stanza-language). ### Trial and Freemium Versions Before submitting a trial, make sure it can be made into a full working version without the need to be redownloaded. If an App provides a trial but the only way to buy the full version is via the Mac App Store, it does not belong in any of the official repos. Freemium versions are fine. ### Forks and Apps with Conflicting Names Forks must have the vendor’s name as a prefix on the Cask’s file name and token. If the original software is discontinued, forks still need to follow this rule so as to not be surprising to the user. There are two exceptions which allow the fork to replace the main cask: * The original discontinued software recommends that fork. * The fork is so overwhelmingly popular that it surpasses the original and is now the de facto project when people think of the name. For unrelated Apps that share a name, the most popular one (usually the one already present) stays unprefixed. Since this can be subjective, if you disagree with a decision, open an issue and make your case to the maintainers. ### Unofficial, Vendorless, and Walled Builds We do not accept these casks since they offer a higher-than-normal security risk. ### Fonts Font Casks live in the [Homebrew/homebrew-cask- fonts](https://github.com/Homebrew/homebrew-cask-fonts) repository. See the font repo [CONTRIBUTING.md](https://github.com/Homebrew/homebrew-cask- fonts/blob/HEAD/CONTRIBUTING.md) for details. ### Drivers Driver Casks live in the [Homebrew/homebrew-cask- drivers](https://github.com/Homebrew/homebrew-cask-drivers) repository. See the drivers repo [CONTRIBUTING.md](https://github.com/Homebrew/homebrew-cask- drivers/blob/master/CONTRIBUTING.md) for details. ## Apps that bundle malware Unfortunately, in the world of software there are bad actors that bundle malware with their apps. Even so, Homebrew Cask has long decided it will not be an active gatekeeper ([macOS already has one](https://support.apple.com/en- us/HT202491)) and users are expected to know about the software they are installing. This means we will not always remove casks that link to these apps, in part because there is no clear line between useful app, potentially unwanted program, and the different shades of malware — what is useful to one user may be seen as malicious by another. But we’d still like for users to enjoy some kind of protection while minimising occurrences of legitimate developers being branded as malware carriers. To do so, we evaluate casks on a case-by-case basis and any user is free to bring a potential malware case to our attention. However, it is important to never forget the last line of defence is _always_ the user. If an app that bundles malware was not signed with an Apple Developer ID and you purposefully disabled or bypassed Gatekeeper, no action will be taken on our part. When you disable security features, you do so at your own risk. If, however, an app that bundles malware is signed, Apple can revoke its permissions and it will no longer run on the computers of users that keep security features on — we all benefit, Homebrew Cask users or not. To report a signed app that bundles malware, use [Apple’s Feedback Assistant](https://feedbackassistant.apple.com) We are also open to removing casks where we feel there is enough evidence that the app is malicious. To suggest a cask for removal, submit a Pull Request to delete it, together with your reasoning. Typically, this will mean presenting a [VirusTotal](https://www.virustotal.com) scan of the app showing it is malicious, ideally with some other reporting indicating it’s not a false positive. Likewise, software which provides both “clean” and malware-infested versions might be removed from the repo — even if we could have access to the _good_ version — if its developers push for users to install the _bad_ version. We do so because in these cases there’s a higher than normal risk that both versions are (or will soon become) compromised in some manner. If a cask you depend on was removed due to these rules, fear not. Removal of a cask from the official repositories means we won’t support it, but you can do so by hosting your own [tap](how-to-create-and-maintain-a-tap). ## Exceptions to the Notability Threshold Casks which do not reach a minimum notability threshold (see Rejected Casks) aren’t accepted in the main repositories because the increased maintenance burden doesn’t justify the poor usage numbers they will likely get. This notability check is performed automatically by the audit commands we provide, but its decisions aren’t set in stone. A cask which fails the notability check can be added if it is: 1. A popular app that has their own website but the developers use GitHub for hosting the binaries. That repository won’t be notable but the app may be. 2. Submitted by a maintainer or prolific contributor. A big part of the reasoning for the notability rule is unpopular software garners less attention and the cask gets abandoned, outdated, and broken. Someone with a proven investment in Hombrew Cask is less likely to let that happen for software they depend on. 3. A piece of software that was recently released to great fanfare—everyone is talking about it on Twitter and Hacker News and we’ve even gotten multiple premature submissions for it. That’s a clear case of an app that will reach the threshold in no time so that’s a PR we won’t close immediately (but may wait to merge). Note none of these exceptions is a guarantee for inclusion, but examples of situations where we may take a second look. ## Homebrew Cask is not a discoverability service From the inception of Homebrew Cask, various requests fell under the umbrella of this reply. Though a somewhat popular request, after careful consideration on multiple occasions we’ve always come back to the same conclusion: we’re not a discoverability service and our users are expected to have reasonable knowledge about the apps they’re installing through us before doing so. For example, [grouping casks by categories](https://github.com/Homebrew/homebrew- cask/issues/5425) is not within the scope of the project. Amongst other things, the logistics of such requests are unsustainable for Homebrew Cask. Before making a request of this nature, you must read through previous related issues, as well as any other issues they link to, to get a full understanding of why that is the case, and why “but project _x_ does _y_ ” arguments aren’t applicable, and not every package manager is the same. You should also be able to present clear actionable fixes to those concerns. Simply asking for it without solutions will get your issue closed. However, there is a difference between discoverability (finding new apps you didn’t know about) and searchability (identifying the app you know about and want to install). While the former is unlikely to ever become part of our goals, the latter is indeed important to us, and we continue to work on it. ## Rejected Casks Before submitting a Cask to any of our repos, you must read our documentation on acceptable Casks and perform a (at least quick) search to see if there were any previous attempts to introduce it. Common reasons to reject a Cask entirely: * We have strong reasons to believe including the Cask can put the whole project at risk. Happened only once so far, [with Popcorn Time](https://github.com/Homebrew/homebrew-cask/pull/3954). * The Cask is unreasonably difficult to maintain. Examples once included [Audacity](https://github.com/Homebrew/homebrew-cask/pull/27517) and [older Java development Casks](https://github.com/Homebrew/homebrew-cask/issues/57387). * The app is a trial version, and the only way to acquire the full version is through the Mac App Store. * Similarly (and trickier to spot), the app has moved to the Mac App Store but still provides old versions via direct download. We reject these in all official repos so users don’t get stuck using an old version, wrongly thinking they’re using the most up-to-date one (which, amongst other things, might be a security risk). * The app is both open-source and CLI-only (i.e. it only uses the `binary` artifact). In that case, and [in the spirit of deduplication](https://github.com/Homebrew/homebrew-cask/issues/15603), submit it first to [Homebrew/core](https://github.com/Homebrew/homebrew-core) as a formula that builds from source. If it is rejected, you may then try again as a cask (link us to the issue so we can see the discussion and reasoning for rejection). * The app is open-source and has a GUI but no compiled versions (or only old ones) are provided. It’s better to have them in [Homebrew/core](https://github.com/Homebrew/homebrew-core) so users don’t get perpetually outdated versions. See [`gedit`](https://github.com/Homebrew/homebrew-cask/pull/23360) for example. * The app has been rejected before due to an issue we cannot fix, and the new submission doesn’t fix that. An example would be [the first submission of `soapui`](https://github.com/Homebrew/homebrew-cask/pull/4939), whose installation problems were not fixed in the two subsequent submissions ([#9969](https://github.com/Homebrew/homebrew-cask/pull/9969), [#10606](https://github.com/Homebrew/homebrew-cask/pull/10606)). * The Cask is a duplicate. These submissions mostly occur when the [token reference](cask-cookbook#token-reference) was not followed. * The download URL for the app is both behind a login/registration form and from a host that differs from the homepage, meaning users can’t easily verify its authenticity. * The Cask is for an unmaintained app (no releases in the last year, or [explicitly discontinued](https://github.com/Homebrew/homebrew-cask/pull/22699)). * The Cask is for an app that is too obscure. Examples: * An app from a code repository that is not notable enough (under 30 forks, 30 watchers, 75 stars). * [Electronic Identification (eID) software](https://github.com/Homebrew/homebrew-cask/issues/59021). * The Cask is for an app with no information on the homepage (example: a GitHub repository without a README). * The author has [specifically asked us not to include it](https://github.com/Homebrew/homebrew-cask/pull/5342). * The Cask requires [SIP to be disabled](https://github.com/Homebrew/homebrew-cask/pull/41890) to be installed and/or used. * The Cask is a `pkg` that requires [`allow_untrusted: true`](cask-cookbook#pkg-allow_untrusted). Common reasons to reject a Cask from the main repo: * The cask was submitted to the wrong repo. When drafting a cask, consult “Finding a Home For Your Cask” to see where it belongs. ## No cask is guaranteed to be accepted Follow the guidelines above and your submission has a great chance of being accepted. But remember documentation tends to lag behind current decision- making and we can’t predict every case. Maintainers may override these rules when experience tells us it will lead to a better overall Homebrew. # Acceptable Formulae Some formulae should not go in [homebrew/core](https://github.com/Homebrew/homebrew-core). But there are additional [Interesting Taps and Forks](interesting-taps-and-forks) and anyone can start their own! ### Supported platforms in `homebrew/core` The formula needs to build and pass tests on the latest 3 supported macOS versions ([x86_64 and Apple Silicon/ARM](installation#macos-requirements)) and on x86_64 [Linux](linux-ci). Please have a look at the continuous integration jobs on a pull request in `homebrew/core` to see the full list of OSs. If upstream does not support one of these platforms, an exception can be made and the formula can be disabled for that platform. ### Dupes in `homebrew/core` We now accept stuff that comes with macOS as long as it uses `keg_only :provided_by_macos` to be keg-only by default. ### Versioned formulae in `homebrew/core` We now accept versioned formulae as long as they [meet the requirements](versions). ### We don’t like tools that upgrade themselves Software that can upgrade itself does not integrate well with Homebrew’s own upgrade functionality. The self-update functionality should be disabled (while minimising complication to the formula). ### We don’t like install scripts that download unversioned things We don’t like install scripts that are pulling from the `master` branch of Git repositories or unversioned, unchecksummed tarballs. These should use `resource` blocks with specific revisions or checksummed tarballs instead. Note that we now allow tools like `cargo`, `gem` and `pip` to download specifically versioned libraries during installation. ### We don’t like binary formulae Our policy is that formulae in the core tap ([homebrew/core](https://github.com/Homebrew/homebrew-core)) must be open- source with an [Debian Free Software Guidelines license](https://wiki.debian.org/DFSGLicenses) and either built from source or produce cross-platform binaries (e.g. Java, Mono). Binary-only formulae should go to [homebrew/cask](https://github.com/Homebrew/homebrew-cask). Additionally, [homebrew/core](https://github.com/Homebrew/homebrew-core) formulae must also not depend on casks or any other proprietary software. This includes automatic installation of casks at runtime. ### Stable versions Formulae in the core repository must have a stable version tagged by the upstream project. Tarballs are preferred to Git checkouts, and tarballs should include the version in the filename whenever possible. We don’t accept software without a tagged version because they regularly break due to upstream changes and we can’t provide [bottles](bottles) for them. ### Niche (or self-submitted) stuff The software in question must: * be maintained (i.e. the last release wasn’t ages ago, it works without patching on all Homebrew-supported OS versions and has no outstanding, unpatched security vulnerabilities) * be known * be stable (e.g. not declared “unstable” or “beta” by upstream) * be used * have a homepage We will reject formulae that seem too obscure, partly because they won’t get maintained and partly because we have to draw the line somewhere. We frown on authors submitting their own work unless it is very popular. Don’t forget Homebrew is all Git underneath! [Maintain your own tap](how-to- create-and-maintain-a-tap) if you have to! There may be exceptions to these rules in the main repository; we may include things that don’t meet these criteria or reject things that do. Please trust that we need to use our discretion based on our experience running a package manager. ### Stuff that builds an `.app` Don’t make your formula build an `.app` (native macOS Application); we don’t want those things in Homebrew. Encourage upstream projects to build and support a `.app` that can be distributed by [homebrew/cask](https://github.com/Homebrew/homebrew-cask) (and used without it, too). ### Stuff that builds a GUI by default (but doesn’t have to) Make it build a command-line tool or a library by default and, if the GUI is useful and would be widely used, also build the GUI. Don’t build X11/XQuartz GUIs as they are a bad user experience on macOS. ### Stuff that doesn’t build with the latest, stable Xcode Clang Clang is the default C/C++ compiler on macOS (and has been for a long time). Software that doesn’t build with it hasn’t been adequately ported to macOS. ### Stuff that requires heavy manual pre/post-install intervention We’re a package manager so we want to do things like resolve dependencies and set up applications for our users. If things require too much manual intervention then they aren’t useful in a package manager. ## Stuff that requires vendored versions of Homebrew formulae Homebrew formulae should avoid having multiple, separate, upstream projects bundled together in a single package to avoid shipping outdated/insecure versions of software that is already a formula. Veracode’s [State of Software Security report](https://www.veracode.com/blog/research/announcing-state- software-security-v11-open-source-edition) concludes > In fact, 79% of the time, developers never update third-party libraries > after including them in a codebase. For more info see [Debian’s](https://www.debian.org/doc/debian-policy/ch- source.html#s-embeddedfiles) and [Fedora’s](https://docs.fedoraproject.org/en- US/packaging-guidelines/#bundling) stances on this. ### Sometimes there are exceptions Even if all criteria are met we may not accept the formula. Documentation tends to lag behind current decision-making. Although some rejections may seem arbitrary or strange they are based on years of experience making Homebrew work acceptably for our users. # Adding Software To Homebrew Is your favorite software missing from Homebrew? Then you’re the perfect person to resolve this problem. If you want to add software that is either closed source or a GUI-only program, you will want to follow the guide for Casks. Otherwise follow the guide for Formulae. See also: [Homebrew Terminology](formula- cookbook#homebrew-terminology) Before you start, please check the open pull requests for [Homebrew/homebrew- core](https://github.com/Homebrew/homebrew-core/pulls) or [Homebrew/homebrew- cask](https://github.com/Homebrew/homebrew-cask/pulls) to make sure no one else beat you to the punch. Next, you will want to go through the [Acceptable Formulae](acceptable- formulae) or [Acceptable Casks](acceptable-casks) documentation to determine if the software is an appropriate addition to Homebrew. If you are creating a formula for an alternative version of software already in Homebrew (e.g. a major/minor version that differs significantly from the existing version), be sure to read the [Versions](versions) documentation to understand versioned formulae requirements. If everything checks out, you’re ready to get started on a new formula! ## Formulae ### Writing the formula 1. It’s a good idea to find existing formulae in Homebrew that have similarities to the software you want to add. This will help you to understand how specific languages, build methods, etc. are typically handled. 2. If you’re starting from scratch, you can use the [`brew create` command](manpage#create-options-url) to produce a basic version of your formula. This command accepts a number of options and you may be able to save yourself some work by using an appropriate template option like `--python`. 3. You will now have to develop the boilerplate code from `brew create` into a full-fledged formula. Your main references will be the [Formula Cookbook](formula-cookbook), similar formulae in Homebrew, and the upstream documentation for your chosen software. Be sure to also take note of the Homebrew documentation for writing [Python](python-for-formula-authors) and [Node](node-for-formula-authors) formulae, if applicable. 4. Make sure you write a good test as part of your formula. Refer to the [Add a test to the formula](formula-cookbook#add-a-test-to-the-formula) section of the Cookbook for help with this. 5. Try installing your formula using `brew install --build-from-source `, where is the name of your formula. If any errors occur, correct your formula and attempt to install it again. The formula installation should finish without errors by the end of this step. If you’re stuck, ask for help on GitHub or [Homebrew/discussions](https://github.com/homebrew/discussions/discussions). The maintainers are very happy to help but we also like to see that you’ve put effort into trying to find a solution first. ### Testing and auditing the formula 1. Run `brew audit --strict --new-formula --online ` with your formula. If any errors occur, correct your formula and run the audit again. The audit should finish without any errors by the end of this step. 2. Run your formula’s test using `brew test `. The test should finish without any errors. ### Submitting the formula You’re finally ready to submit your formula to the [homebrew- core](https://github.com/Homebrew/homebrew-core/) repository. If you haven’t done this before, you can refer to the [How to Open a Pull Request](how-to- open-a-homebrew-pull-request) documentation for help. Maintainers will review the pull request and provide feedback about any areas that need to be addressed before the formula can be added to Homebrew. If you’ve made it this far, congratulations on submitting a Homebrew formula! We appreciate the hard work you put into this and you can take satisfaction in knowing that your work may benefit other Homebrew users as well. ## Casks **Note:** Before taking the time to craft a new cask: * make sure it can be accepted by checking the [Rejected Casks FAQ](acceptable-casks#rejected-casks), and * check that the cask was not [already refused](https://github.com/Homebrew/homebrew-cask/search?q=is%3Aclosed&type=Issues). ### Writing the cask Making a new cask is easy. Follow the directions in [Getting Set Up To Contribute](https://github.com/Homebrew/homebrew- cask/blob/HEAD/CONTRIBUTING.md#getting-set-up-to-contribute) to begin. #### Examples Here’s a cask for `shuttle` as an example. Note the `verified` parameter below the `url`, which is needed when [the url and homepage hostnames differ](cask- cookbook#when-url-and-homepage-domains-differ-add-verified). cask "shuttle" do version "1.2.9" sha256 "0b80bf62922291da391098f979683e69cc7b65c4bdb986a431e3f1d9175fba20" url "https://github.com/fitztrev/shuttle/releases/download/v#{version}/Shuttle.zip", verified: "github.com/fitztrev/shuttle/" name "Shuttle" desc "Simple shortcut menu" homepage "https://fitztrev.github.io/shuttle/" app "Shuttle.app" zap trash: "~/.shuttle.json" end And here is one for `noisy`. Note that it has an unversioned download (the download `url` does not contain the version number, unlike the example above). It also suppresses the checksum with `sha256 :no_check`, which is necessary because since the download `url` does not contain the version number, its checksum will change when a new version is made available. cask "noisy" do version "1.3" sha256 :no_check url "https://github.com/downloads/jonshea/Noisy/Noisy.zip" name "Noisy" desc "White noise generator" homepage "https://github.com/jonshea/Noisy" app "Noisy.app" end Here is a last example for `airdisplay`, which uses a `pkg` installer to install the application instead of a stand-alone application bundle (`.app`). Note the [`uninstall pkgutil` stanza](cask-cookbook#uninstall-key-pkgutil), which is needed to uninstall all files that were installed using the installer. You will also see how to adapt `version` to the download `url`. Use [our custom `version` methods](cask-cookbook#version-methods) to do so, resorting to the standard [Ruby String methods](https://ruby-doc.org/core/String.html) when they don’t suffice. cask "airdisplay" do version "3.4.2,26581" sha256 "272d14f33b3a4a16e5e0e1ebb2d519db4e0e3da17f95f77c91455b354bee7ee7" url "https://www.avatron.com/updates/software/airdisplay/ad#{version.before_comma.no_dots}.zip" name "Air Display" desc "Utility for using a tablet as a second monitor" homepage "https://avatron.com/applications/air-display/" livecheck do url "https://www.avatron.com/updates/software/airdisplay/appcast.xml" strategy :sparkle end depends_on macos: ">= :mojave" pkg "Air Display Installer.pkg" uninstall pkgutil: [ "com.avatron.pkg.AirDisplay", "com.avatron.pkg.AirDisplayHost2", ] end #### Generating a token for the cask The cask **token** is the mnemonic string people will use to interact with the cask via `brew install`, etc. The name of the cask **file** is simply the token with the extension `.rb` appended. The easiest way to generate a token for a cask is to run this command: $(brew --repository homebrew/cask)/developer/bin/generate_cask_token "/full/path/to/new/software.app" If the software you wish to create a cask for is not installed, or does not have an associated App bundle, just give the full proper name of the software instead of a pathname: $(brew --repository homebrew/cask)/developer/bin/generate_cask_token "Google Chrome" If the `generate_cask_token` script does not work for you, see Cask Token Details. #### Creating the cask file Once you know the token, create your cask with the handy-dandy `brew create --cask` command: brew create --cask download-url --set-name my-new-cask This will open `$EDITOR` with a template for your new cask, to be stored in the file `my-new-cask.rb`. Running the `create` command above will get you a template that looks like this: cask "my-new-cask" do version "" sha256 "" url "download-url" name "" desc "" homepage "" app "" end #### Cask stanzas Fill in the following stanzas for your cask: name | value ---|--- `version` | application version `sha256` | SHA-256 checksum of the file downloaded from `url`, calculated by the command `shasum -a 256 `. Can be suppressed by using the special value `:no_check`. (see [`sha256` Stanza Details](cask-cookbook#stanza-sha256)) `url` | URL to the `.dmg`/`.zip`/`.tgz`/`.tbz2` file that contains the application. A [`verified` parameter](cask-cookbook#when-url-and-homepage-domains-differ- add-verified) must be added if the hostnames in the `url` and `homepage` stanzas differ. [Block syntax](cask-cookbook#using-a-block-to-defer-code- execution) is available for URLs that change on every visit `name` | the full and proper name defined by the vendor, and any useful alternate names (see [`name` Stanza Details](cask-cookbook#stanza-name)) `desc` | one-line description of the software (see [`desc` Stanza Details](cask-cookbook#stanza-desc)) `homepage` | application homepage; used for the `brew home` command `app` | relative path to an `.app` bundle that should be moved into the `/Applications` folder on installation (see [`app` Stanza Details](cask-cookbook#stanza-app)) Other commonly used stanzas are: name | value ---|--- `livecheck` | Ruby block describing how to find updates for this cask (see [`livecheck` Stanza Details](cask-cookbook#stanza-livecheck)) `pkg` | relative path to a `.pkg` file containing the distribution (see [`pkg` Stanza Details](cask-cookbook#stanza-pkg)) `caveats` | a string or Ruby block providing the user with cask-specific information at install time (see [`caveats` Stanza Details](cask-cookbook#stanza-caveats)) `uninstall` | procedures to uninstall a cask. Optional unless the `pkg` stanza is used. (see [`uninstall` Stanza Details](cask-cookbook#stanza-uninstall)) `zap` | additional procedures for a more complete uninstall, including configuration files and shared resources (see [`zap` Stanza Details](cask-cookbook#stanza-zap)) Additional [`artifact` stanzas](cask-cookbook#at-least-one-artifact-stanza-is- also-required) may be needed for special use cases. Even more special-use stanzas are listed at [Optional Stanzas](cask-cookbook#optional-stanzas). #### Cask token details If a token conflicts with an already-existing cask, authors should manually make the new token unique by prepending the vendor name. Example: [unison.rb](https://github.com/Homebrew/homebrew- cask/blob/HEAD/Casks/unison.rb) and [panic- unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/panic- unison.rb). If possible, avoid creating tokens that differ only by the placement of hyphens. To generate a token manually, or to learn about exceptions for unusual cases, see the [Token Reference](cask-cookbook#token-reference). #### Archives with subfolders When a downloaded archive expands to a subfolder, the subfolder name must be included in the `app` value. Example: 1. Texmaker is downloaded to the file `TexmakerMacosxLion.zip`. 2. `TexmakerMacosxLion.zip` unzips to a folder called `TexmakerMacosxLion`. 3. The folder `TexmakerMacosxLion` contains the application `texmaker.app`. 4. So, the `app` stanza should include the subfolder as a relative path: app "TexmakerMacosxLion/texmaker.app" ### Testing and auditing the cask Give it a shot with: export HOMEBREW_NO_AUTO_UPDATE=1 brew install my-new-cask Did it install? If something went wrong, edit your cask with `brew edit my- new-cask` to fix it. Test also if the uninstall works successfully: brew uninstall my-new-cask If everything looks good, you’ll also want to make sure your cask passes audit with: brew audit --new-cask my-new-cask You should also check stylistic details with `brew style`: brew style --fix my-new-cask Keep in mind that all these checks will be made when you submit your PR, so by doing them in advance you’re saving everyone a lot of time and trouble. If your application and Homebrew Cask do not work well together, feel free to [file an issue](https://github.com/Homebrew/homebrew-cask#reporting-bugs) after checking out open issues. ### Submitting the cask #### Finding a home for your cask See the [Acceptable Casks documentation](acceptable-casks#finding-a-home-for- your-cask). Hop into your Tap and check to make sure your new cask is there: $ cd "$(brew --repository)"/Library/Taps/homebrew/homebrew-cask $ git status # On branch master # Untracked files: # (use "git add ..." to include in what will be committed) # # Casks/my-new-cask.rb So far, so good. Now make a feature branch `my-new-cask-branch` that you’ll use in your pull request: $ git checkout -b my-new-cask-branch Switched to a new branch 'my-new-cask-branch' Stage your cask with: git add Casks/my-new-cask.rb You can view the changes that are to be committed with: git diff --cached Commit your changes with: git commit -v #### Commit messages For any Git project, some good rules for commit messages are: * The first line is the commit summary, 50 characters or less, * Followed by an empty line, * Followed by an explanation of the commit, wrapped to 72 characters. See [A Note About Git Commit Messages](https://tbaggery.com/2008/04/19/a-note- about-git-commit-messages.html) for more. The first line of a commit message becomes the **title** of a pull request on GitHub, like the subject line of an email. Including the key info in the first line will help us respond faster to your pull request. For cask commits in the Homebrew Cask project, we like to include the application name, version number, and purpose of the commit in the first line. Examples of good, clear commit summaries: * `Add Transmission.app v1.0` * `Upgrade Transmission.app to v2.82` * `Fix checksum in Transmission.app cask` * `Add CodeBox Latest` Examples of difficult, unclear commit summaries: * `Upgrade to v2.82` * `Checksum was bad` #### Pushing Push your changes on the branch `my-new-cask-branch` to your GitHub account: git push my-new-cask-branch If you are using [GitHub two-factor authentication](https://docs.github.com/en/authentication/securing-your- account-with-two-factor-authentication-2fa) and have set your remote repository as HTTPS you will need to [set up a personal access token](https://docs.github.com/en/repositories/creating-and-managing- repositories/troubleshooting-cloning-errors#provide-an-access-token) and use that instead of your password. #### Filing a pull request on GitHub ##### a) use suggestion from `git push` The `git push` command prints a suggestion for how to create a pull request: remote: Create a pull request for 'new-cask-cask' on GitHub by visiting: remote: https://github.com//homebrew-cask/pull/new/my-new-cask-branch ##### b) use suggestion from GitHub’s website Now go to the [`homebrew-cask` GitHub repository](https://github.com/Homebrew/homebrew-cask). GitHub will often show your `my-new-cask-branch` branch with a handy button to `Compare & pull request`. ##### c) manually create a pull request on GitHub Otherwise, click the `Contribute > Open pull request` button and choose to `compare across forks`. The base fork should be `Homebrew/homebrew-cask @ master`, and the head fork should be `my-github-username/homebrew-cask @ my- new-cask-branch`. You can also add any further comments to your pull request at this stage. ##### Congratulations! You are done now, and your cask should be pulled in or otherwise noticed in a while. If a maintainer suggests some changes, just make them on the `my-new- cask-branch` branch locally and push. ### Cleaning up After your pull request is submitted, you should get yourself back onto `master`, so that `brew update` will pull down new casks properly: cd "$(brew --repository)"/Library/Taps/homebrew/homebrew-cask git checkout master If earlier you set the variable `HOMEBREW_NO_AUTO_UPDATE` then clean it up with: unset HOMEBREW_NO_AUTO_UPDATE # Anonymous Aggregate User Behaviour Analytics Homebrew gathers anonymous aggregate user behaviour analytics using Google Analytics. You will be notified the first time you run `brew update` or install Homebrew. Analytics are not enabled until after this notice is shown, to ensure that you can [opt out](analytics#opting-out) without ever sending analytics data. ## Why? Homebrew is provided free of charge and run entirely by volunteers in their spare time. As a result, we do not have the resources to do detailed user studies of Homebrew users to decide on how best to design future features and prioritise current work. Anonymous aggregate user analytics allow us to prioritise fixes and features based on how, where and when people use Homebrew. For example: * If a formula is widely used and is failing often it will enable us to prioritise fixing that formula over others. * Collecting the OS version allows us to decide which versions of macOS to prioritise for support and identify build failures that occur only on single versions. ## How Long? Homebrew’s anonymous user and event data have a 14 month retention period. This is the [lowest possible value for Google Analytics](https://support.google.com/analytics/answer/7667196). ## What? Homebrew’s analytics record some shared information for every event: * The Homebrew user agent, e.g. `Homebrew/3.3.0 (Macintosh; Intel Mac OS X 10.15.6) curl/7.64.1`. * The [Google Analytics version](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#v), i.e. `1`. * The Homebrew [analytics tracking ID](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#tid), e.g. `UA-75654628-1`. * A Homebrew [analytics user ID](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#cid), e.g. `1BAB65CC-FE7F-4D8C-AB45-B7DB5A6BA9CB`. This is generated by `uuidgen` and stored in the repository-specific Git configuration variable `homebrew.analyticsuuid` within `$(brew --repository)/.git/config`. This does not allow us to track individual users, but does enable us to accurately measure user counts versus event counts. The ID is specific to the Homebrew package manager, and does not permit Homebrew maintainers to e.g. track you across websites you visit. * Whether the [Google Analytics anonymous IP setting](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#aip) is enabled, i.e. `1`. * The Homebrew [application name](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#an), e.g. `Homebrew`. * The Homebrew [application version](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#av), e.g. `2.5.0`. * The Homebrew [analytics hit type](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#t), e.g. `event`. Homebrew’s analytics records the following different events: * An `event` hit type with the `install` event category and the Homebrew formula from a non-private GitHub tap you install plus any used options (e.g. `wget --HEAD`) as the action, and an event label (e.g. `macOS 10.15, non-/usr/local, CI`) to indicate the OS version, non-standard installation location and invocation as part of CI. This allows us to identify which formulae need fixing and where more easily. * An `event` hit type with the `install_on_request` event category and the Homebrew formula from a non-private GitHub tap you have requested to install (e.g. when explicitly named with a `brew install`) plus options and an event label as above. This allows us to differentiate the formulae that users intend to install from those pulled in as dependencies. * An `event` hit type with the `cask_install` event category and the Homebrew cask from a non-private GitHub tap you install as the action and an event label as above. This allows us to identify which casks need fixing and where more easily. * An `event` hit type with the `BuildError` event category and the Homebrew formula plus options that failed to install as the action and an event label as above, e.g. `wget --HEAD` and `macOS 10.15`. You can also view all the information that is sent by Homebrew’s analytics by setting `HOMEBREW_ANALYTICS_DEBUG=1` in your environment. Please note this will also stop any analytics from being sent. It is impossible for the Homebrew developers to match any particular event to any particular user, even if we had access to the Homebrew analytics user ID (which we do not). An example of the most user-specific information we can see from Google Analytics: As far as we can tell it would be impossible for Google to match the randomly generated Homebrew-only analytics user ID to any other Google Analytics user ID. If Google turned evil the only thing they could do would be to lie about anonymising IP addresses and attempt to match users based on IP addresses. ## When/Where? Homebrew’s analytics are sent throughout Homebrew’s execution to Google Analytics over HTTPS. ## Who? Summaries of installation and error analytics are [publicly available](https://formulae.brew.sh/analytics/). A JSON API is also available. The majority of Homebrew maintainers are not granted more detailed analytics data beyond these public resources. ## How? The code is viewable in [`analytics.rb`](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/utils/analytics.rb) and [`analytics.sh`](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/utils/analytics.sh). They are done in a separate background process and fail fast to avoid delaying any execution. They will fail immediately and silently if you have no network connection. ## Opting out Homebrew analytics helps us maintainers and leaving it on is appreciated. However, if you want to opt out of Homebrew’s analytics, you can set this variable in your environment: export HOMEBREW_NO_ANALYTICS=1 Alternatively, this will prevent analytics from ever being sent: brew analytics off # Bottles (Binary Packages) Bottles are produced by installing a formula with `brew install --build-bottle ` and then bottling it with `brew bottle `. This generates a bottle file in the current directory and outputs the bottle DSL for insertion into the formula file. ## Usage When the formula being installed defines a bottle matching your system, it will be downloaded and installed automatically when you run `brew install `. Bottles will not be used if: * the user requests it (by specifying `--build-from-source`), * the formula requests it (with `pour_bottle?`), * any options are specified during installation (bottles are all compiled with default options), * the bottle is not up to date (e.g. missing or mismatched checksum), * or the bottle’s `cellar` is neither `:any` (it requires being installed to a specific Cellar path) nor equal to the current `HOMEBREW_CELLAR` (the required Cellar path does not match that of the current Homebrew installation). ## Creation Bottles for `homebrew/core` formulae are created by [Brew Test Bot](brew-test- bot) when a pull request is submitted. If the formula builds successfully on each supported platform and a maintainer approves the change, Brew Test Bot updates its `bottle do` block and uploads each bottle to [GitHub Packages](https://github.com/orgs/Homebrew/packages). By default, bottles will be built for the oldest CPU supported by the OS/architecture you’re building for (Core 2 for 64-bit x86 operating systems). This ensures that bottles are compatible with all computers you might distribute them to. If you _really_ want your bottles to be optimised for something else, you can pass the `--bottle-arch=` option to build for another architecture; for example, `brew install foo --build-bottle --bottle- arch=penryn`. Just remember that if you build for a newer architecture, some of your users might get binaries they can’t run and that would be sad! ## Format Bottles are simple gzipped tarballs of compiled binaries. The formula name, version, target operating system and rebuild version is stored in the filename, any other metadata is in the formula’s bottle DSL, and the formula definition is located within the bottle at `//.brew/.rb`. ## Bottle DSL (Domain Specific Language) Bottles are specified in formula definitions by a DSL contained within a `bottle do ... end` block. A simple (and typical) example: bottle do sha256 arm64_big_sur: "a9ae578b05c3da46cedc07dd428d94a856aeae7f3ef80a0f405bf89b8cde893a" sha256 big_sur: "5dc376aa20241233b76e2ec2c1d4e862443a0250916b2838a1ff871e8a6dc2c5" sha256 catalina: "924afbbc16549d8c2b80544fd03104ff8c17a4b1460238e3ed17a1313391a2af" sha256 mojave: "678d338adc7d6e8c352800fe03fc56660c796bd6da23eda2b1411fed18bd0d8d" end A full example: bottle do root_url "https://example.com" rebuild 4 sha256 cellar: "/opt/homebrew/Cellar", arm64_big_sur: "a9ae578b05c3da46cedc07dd428d94a856aeae7f3ef80a0f405bf89b8cde893a" sha256 cellar: :any, big_sur: "5dc376aa20241233b76e2ec2c1d4e862443a0250916b2838a1ff871e8a6dc2c5" sha256 catalina: "924afbbc16549d8c2b80544fd03104ff8c17a4b1460238e3ed17a1313391a2af" sha256 mojave: "678d338adc7d6e8c352800fe03fc56660c796bd6da23eda2b1411fed18bd0d8d" end ### Root URL (`root_url`) Optionally contains the URL root used to determine bottle URLs. By default this is omitted and Homebrew’s default bottle URL root is used. This may be useful for taps that wish to provide bottles for their formulae or cater to a non-default `HOMEBREW_CELLAR`. ### Cellar (`cellar`) Optionally contains the value of `HOMEBREW_CELLAR` in which the bottles were built. Most compiled software contains references to its compiled location, preventing it from being simply relocated anywhere on disk. A value of `:any` or `:any_skip_relocation` means that the bottle can be safely installed in any Cellar as it did not contain any references to the Cellar in which it was originally built. This can be omitted if the bottle was compiled for the given OS/architecture’s default `HOMEBREW_CELLAR`, as is done for all bottles built by Brew Test Bot. ### Rebuild version (`rebuild`) Optionally contains the rebuild version of the bottle. Sometimes bottles may need be updated without bumping the version or revision of the formula, e.g. if a new patch was applied. In such cases `rebuild` will have a value of `1` or more. ### Checksum (`sha256`) Contains the SHA-256 hash of the bottle for the given OS/architecture. ## Formula DSL An additional bottle-related method is available in the formula DSL. ### Pour bottle (`pour_bottle?`) Optionally returns a boolean to indicate whether a bottle should be used when installing this formula. For example a bottle may break if a related formula has been compiled with non-default options, so this method could check for that case and return `false`. A full example: pour_bottle? do reason "The bottle needs to be installed into #{Homebrew::DEFAULT_PREFIX}." satisfy { HOMEBREW_PREFIX.to_s == Homebrew::DEFAULT_PREFIX } end Commonly used `pour_bottle?` conditions can be added as preset symbols to the `pour_bottle?` method, allowing them to be specified like this: pour_bottle? only_if: :default_prefix pour_bottle? only_if: :clt_installed # `brew livecheck` The `brew livecheck` command finds the newest version of a formula or cask’s software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior When livecheck isn’t given instructions for how to check for upstream versions, it does the following by default: 1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order. 2. Determine if any strategies apply to the first URL. If not, try the next URL. 3. If a strategy can be applied, use it to check for new versions. 4. Return the newest version (or an error if versions could not be found at any available URLs). It’s sometimes necessary to override this default behavior to create a working check. If a source doesn’t provide the newest version, we need to check a different one. If livecheck doesn’t correctly match version text, we need to provide an appropriate regex or `strategy` block. This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ## Creating a check 1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. 2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn’t work, try to find a page that links to the file (e.g. a download page). If it’s not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. 3. **Create a regex, if necessary**. If the check works without a regex and wouldn’t benefit from having one, it’s usually fine to omit it. More information on creating regexes can be found in the regex guidelines section. ### General guidelines * **Only use`strategy` when it’s necessary**. For example, if livecheck is already using `Git` for a URL, it’s not necessary to use `strategy :git`. However, if `Git` applies to a URL but we need to use `PageMatch`, it’s necessary to specify `strategy :page_match`. * **Only use the`GithubLatest` strategy when it’s necessary and correct**. `github.com` rate limits requests and we try to minimize our use of this strategy to avoid hitting the rate limit on CI or when using `brew livecheck --tap` on large taps (e.g. homebrew/core). The `Git` strategy is often sufficient and we only need to use `GithubLatest` when the “latest” release is different than the newest version from the tags. ### URL guidelines * **A`url` is required in a `livecheck` block**. This can be a URL string (e.g. `"https://www.example.com/downloads/"`) or a formula/cask URL symbol (i.e. `:stable`, `:url`, `:head`, `:homepage`). The exception to this rule is a `livecheck` block that only uses `skip`. * **Check for versions in the same location as the stable archive, whenever possible**. * **Avoid checking paginated release pages, when possible**. For example, we generally avoid checking the `release` page for a GitHub project because the latest stable version can be pushed off the first page by pre-release versions. In this scenario, it’s more reliable to use the `Git` strategy, which fetches all the tags in the repository. ### Regex guidelines The `livecheck` block regex restricts matches to a subset of the fetched content and uses a capture group around the version text. * **Regexes should be made case insensitive, whenever possible** , by adding `i` at the end (e.g. `/.../i` or `%r{...}i`). This improves reliability, as the regex will handle changes in letter case without needing modifications. * **Regexes should only use a capturing group around the version text**. For example, in `/href=.*?example-v?(\d+(?:\.\d+)+)(?:-src)?\.t/i`, we’re only using a capturing group around the version test (matching a version like `1.2`, `1.2.3`, etc.) and we’re using non-capturing groups elsewhere (e.g. `(?:-src)?`). * **Anchor the start/end of the regex, to restrict the scope**. For example, on HTML pages we often match file names or version directories in `href` attribute URLs (e.g. `/href=.*?example[._-]v?(\d+(?:\.\d+)+)\.zip/i`). The general idea is that limiting scope will help exclude unwanted matches. * **Avoid generic catch-alls like`.*` or `.+`** in favor of something non-greedy and/or contextually appropriate. For example, to match characters within the bounds of an HTML attribute, use `[^"' >]+?`. * **Use`[._-]` in place of a period/underscore/hyphen between the software name and version in a file name**. For a file named `example-1.2.3.tar.gz`, `example[._-]v?(\d+(?:\.\d+)+)\.t` will continue matching if the upstream file name format changes to `example_1.2.3.tar.gz` or `example.1.2.3.tar.gz`. * **Use`\.t` in place of `\.tgz`, `\.tar\.gz`, etc.** There are a variety of different file extensions for tarballs (e.g. `.tar.bz2`, `tbz2`, `.tar.gz`, `.tgz`, `.tar.xz`, `.txz`, etc.) and the upstream source may switch from one compression format to another over time. `\.t` avoids this issue by matching current and future formats starting with `t`. Outside of tarballs, we use the full file extension in the regex like `\.zip`, `\.jar`, etc. ## Example `livecheck` blocks The following examples cover a number of patterns that you may encounter. These are intended to be representative samples and can be easily adapted. When in doubt, start with one of these examples instead of copy-pasting a `livecheck` block from a random formula/cask. ### File names When matching the version from a file name on an HTML page, we often restrict matching to `href` attributes. `href=.*?` will match the opening delimiter (`"`, `'`) as well as any part of the URL before the file name. livecheck do url "https://www.example.com/downloads/" regex(/href=.*?example[._-]v?(\d+(?:\.\d+)+)\.t/i) end We sometimes make this more explicit to exclude unwanted matches. URLs with a preceding path can use `href=.*?/` and others can use `href=["']?`. For example, this is necessary when the page also contains unwanted files with a longer prefix (`another-example-1.2.tar.gz`). ### Version directories When checking a directory listing page, sometimes files are separated into version directories (e.g. `1.2.3/`). In this case, we must identify versions from the directory names. livecheck do url "https://www.example.com/releases/example/" regex(%r{href=["']?v?(\d+(?:\.\d+)+)/?["' >]}i) end ### Git tags When the `stable` URL uses the `Git` strategy, the following example will only match tags like `1.2`/`v1.2`, etc. livecheck do url :stable regex(/^v?(\d+(?:\.\d+)+)$/i) end If tags include the software name as a prefix (e.g. `example-1.2.3`), it’s easy to modify the regex accordingly: `/^example[._-]v?(\d+(?:\.\d+)+)$/i` ### Referenced formula/cask A formula/cask can use the same check as another by using `formula` or `cask`. livecheck do formula "another-formula" end The referenced formula/cask should be in the same tap, as a reference to a formula/cask from another tap will generate an error if the user doesn’t already have it tapped. ### `strategy` blocks If the upstream version format needs to be manipulated to match the formula/cask format, a `strategy` block can be used instead of a `regex`. #### `PageMatch` `strategy` block In the example below, we’re converting a date format like `2020-01-01` into `20200101`. livecheck do url :homepage strategy :page_match do |page| page.scan(/href=.*?example[._-]v?(\d{4}-\d{2}-\d{2})\.t/i) .map { |match| match&.first&.gsub(/\D/, "") } end end The `PageMatch` `strategy` block style seen here also applies to any strategy that uses `PageMatch` internally. #### `Git` `strategy` block A `strategy` block for `Git` is a bit different, as the block receives an array of tag strings instead of a page content string. Similar to the `PageMatch` example, this is converting tags with a date format like `2020-01-01` into `20200101`. livecheck do url :stable strategy :git do |tags| tags.map { |tag| tag[/^(\d{4}-\d{2}-\d{2})$/i, 1]&.gsub(/\D/, "") }.compact end end #### `Sparkle` `strategy` block A `strategy` block for `Sparkle` receives an `item` which has methods for the `short_version`, `version`, `url` and `title`. The default pattern for the `Sparkle` strategy is `"#{item.short_version},#{item.version}"` if both are set. In the example below, the `url` also includes a download ID which is needed: livecheck do url "https://www.example.com/example.xml" strategy :sparkle do |item| "#{item.short_version},#{item.version}:#{item.url[%r{/(\d+)/[^/]+\.zip}i, 1]}" end end ### `skip` Livecheck automatically skips some formulae/casks for a number of reasons (deprecated, disabled, discontinued, etc.). However, on rare occasions we need to use a `livecheck` block to do a manual skip. The `skip` method takes a string containing a very brief reason for skipping. livecheck do skip "No version information available" end # Brew Test Bot `brew test-bot` is the name for the automated review and testing system funded by [our Kickstarter in 2013](https://www.kickstarter.com/projects/homebrew/brew-test-bot). It comprises three Mac Pros hosting virtual machines that run the [`test- bot.rb`](https://github.com/Homebrew/homebrew-test-bot/) external command to perform automated testing of commits to the master branch, pull requests and custom builds requested by maintainers. ## Pull Requests The bot automatically builds pull requests and updates their status depending on the result of the job. For example, a job which has been queued but not yet completed will have a section in the pull request that looks like this: * * * A failed build looks like this: * * * A passed build looks like this: * * * On failed or passed builds you can click the “Details” link to view the result in GitHub Actions. # Building Against Non-Homebrew Dependencies ## History Originally Homebrew was a build-from-source package manager and all user environment variables and non-Homebrew-installed software were available to builds. Since then Homebrew added `Requirement`s to specify dependencies on non-Homebrew software (such as those provided by `brew cask` like X11/XQuartz), the `superenv` build system to strip out unspecified dependencies, environment filtering to stop the user environment leaking into Homebrew builds and `default_formula` to specify that a `Requirement` can be satisfied by a particular formula. As Homebrew became primarily a binary package manager, most users were fulfilling `Requirement`s with the `default_formula`, not with arbitrary alternatives. To improve quality and reduce variation, Homebrew now exclusively supports using the default formula, as an ordinary dependency, and no longer supports using arbitrary alternatives. ## Today If you wish to build against custom non-Homebrew dependencies that are provided by Homebrew (e.g. a non-Homebrew, non-macOS `ruby`) then you must [create and maintain your own tap](how-to-create-and-maintain-a-tap) as these formulae will not be accepted in Homebrew/homebrew-core. Once you have done that you can specify `env :std` in the formula which will allow e.g. `which ruby` to access your existing `PATH` variable and allow compilation to link against this Ruby. You can also [include a custom Requirement](https://github.com/Homebrew/brew/tree/HEAD/Library/Homebrew/requirements) in your formula that more accurately describes the non-Homebrew software you build against. # C++ Standard Libraries There are two C++ standard libraries supported by Apple compilers. The default for 10.9 and later is **libc++** , which is also the default for `clang` on older platforms when building C++11 code. The default for 10.8 and earlier was **libstdc++** , supported by Apple GCC compilers, GNU GCC compilers, and `clang`. This was marked deprecated with a warning during compilation as of Xcode 8. There are subtle incompatibilities between several of the C++ standard libraries, so Homebrew will refuse to install software if a dependency was built with an incompatible C++ library. It’s recommended that you install the dependency tree using a compatible compiler. **If you’ve upgraded to 10.9 or later from an earlier version:** Because the default C++ standard library is now libc++, you may not be able to build software using dependencies that you built on 10.8 or earlier. If you’re reading this page because you were directed here by a build error, you can most likely fix the issue if you reinstall all the dependencies of the package you’re trying to build. Example install using GCC 7: brew install gcc@7 brew install --cc=gcc-7 # Cask Cookbook Each Cask is a Ruby block, beginning with a special header line. The Cask definition itself is always enclosed in a `do … end` block. Example: cask "alfred" do version "2.7.1_387" sha256 "a3738d0513d736918a6d71535ef3d85dd184af267c05698e49ac4c6b48f38e17" url "https://cachefly.alfredapp.com/Alfred_#{version}.zip" name "Alfred" desc "Application launcher and productivity software" homepage "https://www.alfredapp.com/" app "Alfred 2.app" app "Alfred 2.app/Contents/Preferences/Alfred Preferences.app" end ## The Cask Language Is Declarative Each Cask contains a series of stanzas (or “fields”) which _declare_ how the software is to be obtained and installed. In a declarative language, the author does not need to worry about **order**. As long as all the needed fields are present, Homebrew Cask will figure out what needs to be done at install time. To make maintenance easier, the most-frequently-updated stanzas are usually placed at the top. But that’s a convention, not a rule. Exception: `do` blocks such as `postflight` may enclose a block of pure Ruby code. Lines within that block follow a procedural (order-dependent) paradigm. ## Conditional Statements ### Efficiency Conditional statements are permitted, but only if they are very efficient. Tests on the following values are known to be acceptable: value | examples ---|--- `MacOS.version` | [coconutbattery.rb](https://github.com/Homebrew/homebrew-cask/blob/a11ee55e8ed8255f7dab77120dfb1fb955789559/Casks/coconutbattery.rb#L2-L16), [yasu.rb](https://github.com/Homebrew/homebrew-cask/blob/21d3f7ac8a4adac0fe474b3d4b020d284eeef88d/Casks/yasu.rb#L2-L23) ### Version Comparisons Tests against `MacOS.version` may use either symbolic names or version strings with numeric comparison operators: if MacOS.version <= :mojave # symbolic name if MacOS.version <= "10.14" # version string The available symbols for macOS versions are: `:el_capitan`, `:sierra`, `:high_sierra`, `:mojave`, `:catalina` and `:big_sur`. The corresponding numeric version strings should be given as major releases containing a single dot. Note that in the official Homebrew Cask repositories only the symbolic names are allowed. The numeric comparison may only be used for third-party taps. ### Always Fall Through to the Newest Case Conditionals should be constructed so that the default is the newest OS version. When using an `if` statement, test for older versions, and then let the `else` statement hold the latest and greatest. This makes it more likely that the Cask will work without alteration when a new OS is released. Example (from [coconutbattery.rb](https://github.com/Homebrew/homebrew- cask/blob/2c801af44be29fff7f3cb2996455fce5dd95d1cc/Casks/coconutbattery.rb)): if MacOS.version <= :sierra # ... elsif MacOS.version <= :mojave # ... else # ... end ### Switch Between Languages or Regions If a cask is available in multiple languages, you can use the `language` stanza to switch between languages or regions based on the system locale. ## Arbitrary Ruby Methods In the exceptional case that the Cask DSL is insufficient, it is possible to define arbitrary Ruby variables and methods inside the Cask by creating a `Utils` namespace. Example: cask "myapp" do module Utils def self.arbitrary_method ... end end name "MyApp" version "1.0" sha256 "a32565cdb1673f4071593d4cc9e1c26bc884218b62fef8abc450daa47ba8fa92" url "https://#{Utils.arbitrary_method}" homepage "https://www.example.com/" ... end This should be used sparingly: any method which is needed by two or more Casks should instead be rolled into the core. Care must also be taken that such methods be very efficient. Variables and methods should not be defined outside the `Utils` namespace, as they may collide with Homebrew Cask internals. ## Header Line Details The first non-comment line in a Cask follows the form: cask "" do `` should match the Cask filename, without the `.rb` extension, enclosed in single quotes. There are currently some arbitrary limitations on Cask tokens which are in the process of being removed. GitHub Actions will catch any errors during the transition. ## Stanza order Having a common order for stanzas makes Casks easier to update and parse. Below is the complete stanza sequence (no Cask will have all stanzas). The empty lines shown here are also important, as they help to visually delineate information. version sha256 language url appcast name desc homepage livecheck auto_updates conflicts_with depends_on container suite app pkg installer binary manpage colorpicker dictionary font input_method internet_plugin prefpane qlplugin mdimporter screen_saver service audio_unit_plugin vst_plugin vst3_plugin artifact, target: # target: shown here as is required with `artifact` stage_only preflight postflight uninstall_preflight uninstall_postflight uninstall zap caveats Note that every stanza that has additional parameters (`:symbols` after a `,`) shall have them on separate lines, one per line, in alphabetical order. An exception is `target:` which typically consists of short lines. ## Stanzas ### Required Stanzas Each of the following stanzas is required for every Cask. name | multiple occurrences allowed? | value ---|---|--- `version` | no | Application version. See Version Stanza Details for more information. `sha256` | no | SHA-256 checksum of the file downloaded from `url`, calculated by the command `shasum -a 256 `. Can be suppressed by using the special value `:no_check`. See Checksum Stanza Details for more information. `url` | no | URL to the `.dmg`/`.zip`/`.tgz`/`.tbz2` file that contains the application. A comment should be added if the hostnames in the `url` and `homepage` stanzas differ. Block syntax should be used for URLs that change on every visit. See URL Stanza Details for more information. `name` | yes | String providing the full and proper name defined by the vendor. See Name Stanza Details for more information. `desc` | no | One-line description of the Cask. Shows when running `brew info`. See Desc Stanza Details for more information. `homepage` | no | Application homepage; used for the `brew home` command. ### At Least One Artifact Stanza Is Also Required Each Cask must declare one or more _artifacts_ (i.e. something to install). name | multiple occurrences allowed? | value ---|---|--- `app` | yes | Relative path to an `.app` that should be moved into the `/Applications` folder on installation. See App Stanza Details for more information. `pkg` | yes | Relative path to a `.pkg` file containing the distribution. See Pkg Stanza Details for more information. `binary` | yes | Relative path to a Binary that should be linked into the `$(brew --prefix)/bin` folder (typically `/usr/local/bin`) on installation. See Binary Stanza Details for more information. `colorpicker` | yes | Relative path to a ColorPicker plugin that should be moved into the `~/Library/ColorPickers` folder on installation. `dictionary` | yes | Relative path to a Dictionary that should be moved into the `~/Library/Dictionaries` folder on installation. `font` | yes | Relative path to a Font that should be moved into the `~/Library/Fonts` folder on installation. `input_method` | yes | Relative path to a Input Method that should be moved into the `~/Library/Input Methods` folder on installation. `internet_plugin` | yes | Relative path to a Service that should be moved into the `~/Library/Internet Plug-Ins` folder on installation. `manpage` | yes | Relative path to a Man Page that should be linked into the respective man page folder on installation, e.g. `/usr/local/share/man/man3` for `my_app.3`. `prefpane` | yes | Relative path to a Preference Pane that should be moved into the `~/Library/PreferencePanes` folder on installation. `qlplugin` | yes | Relative path to a QuickLook Plugin that should be moved into the `~/Library/QuickLook` folder on installation. `mdimporter` | yes | Relative path to a Spotlight metadata importer that should be moved into the `~/Library/Spotlight` folder on installation. `screen_saver` | yes | Relative path to a Screen Saver that should be moved into the `~/Library/Screen Savers` folder on installation. `service` | yes | Relative path to a Service that should be moved into the `~/Library/Services` folder on installation. `audio_unit_plugin` | yes | Relative path to an Audio Unit plugin that should be moved into the `~/Library/Audio/Components` folder on installation. `vst_plugin` | yes | Relative path to a VST Plugin that should be moved into the `~/Library/Audio/VST` folder on installation. `vst3_plugin` | yes | Relative path to a VST3 Plugin that should be moved into the `~/Library/Audio/VST3` folder on installation. `suite` | yes | Relative path to a containing directory that should be moved into the `/Applications` folder on installation. See Suite Stanza Details for more information. `artifact` | yes | Relative path to an arbitrary path that should be moved on installation. Must provide an absolute path as a `target` (example [alcatraz.rb](https://github.com/Homebrew/homebrew-cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/alcatraz.rb#L12)). This is only for unusual cases. The `app` stanza is strongly preferred when moving `.app` bundles. `installer` | yes | Describes an executable which must be run to complete the installation. See Installer Stanza Details for more information. `stage_only` | no | `true`. Assert that the Cask contains no activatable artifacts. ### Optional Stanzas name | multiple occurrences allowed? | value ---|---|--- `uninstall` | yes | Procedures to uninstall a Cask. Optional unless the `pkg` stanza is used. See Uninstall Stanza Details for more information. `zap` | yes | Additional procedures for a more complete uninstall, including user files and shared resources. See Zap Stanza Details for more information. `appcast` | no | URL providing an appcast feed to find updates for this Cask. See Appcast Stanza Details for more information. `depends_on` | yes | List of dependencies and requirements for this Cask. See Depends_on Stanza Details for more information. `conflicts_with` | yes | List of conflicts with this Cask (_not yet functional_). See Conflicts_with Stanza Details for more information. `caveats` | yes | String or Ruby block providing the user with Cask-specific information at install time. See Caveats Stanza Details for more information. `livecheck` | no | Ruby block describing how to find updates for this Cask. See Livecheck Stanza Details for more information. `preflight` | yes | Ruby block containing preflight install operations (needed only in very rare cases). `postflight` | yes | Ruby block containing postflight install operations. See Postflight Stanza Details for more information. `uninstall_preflight` | yes | Ruby block containing preflight uninstall operations (needed only in very rare cases). `uninstall_postflight` | yes | Ruby block containing postflight uninstall operations. `language` | required | Ruby block, called with language code parameters, containing other stanzas and/or a return value. See Language Stanza Details for more information. `container nested:` | no | Relative path to an inner container that must be extracted before moving on with the installation. This allows us to support dmg inside tar, zip inside dmg, etc. `container type:` | no | Symbol to override container-type autodetect. May be one of: `:air`, `:bz2`, `:cab`, `:dmg`, `:generic_unar`, `:gzip`, `:otf`, `:pkg`, `:rar`, `:seven_zip`, `:sit`, `:tar`, `:ttf`, `:xar`, `:zip`, `:naked`. (Example: [parse.rb](https://github.com/Homebrew/homebrew-cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/parse.rb#L11)) `auto_updates` | no | `true`. Assert the Cask artifacts auto-update. Use if `Check for Updates…` or similar is present in app menu, but not if it only opens a webpage and does not do the download and installation for you. ## Stanza descriptions ### Stanza: `app` In the simple case of a string argument to `app`, the source file is moved to the target `/Applications` directory. For example: app "Alfred 2.app" by default moves the source to: /Applications/Alfred 2.app #### Renaming the Target You can rename the target which appears in your `/Applications` directory by adding a `target:` key to `app`. Example (from [scala- ide.rb](https://github.com/Homebrew/homebrew- cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/scala-ide.rb#L21)): app "eclipse/Eclipse.app", target: "Scala IDE.app" #### target: May Contain an Absolute Path If `target:` has a leading slash, it is interpreted as an absolute path. The containing directory for the absolute path will be created if it does not already exist. Example (from [manopen.rb](https://github.com/Homebrew/homebrew- cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/manopen.rb#L12)): artifact "openman.1", target: "/usr/local/share/man/man1/openman.1" #### target: Works on Most Artifact Types The `target:` key works similarly for most Cask artifacts, such as `app`, `binary`, `colorpicker`, `dictionary`, `font`, `input_method`, `prefpane`, `qlplugin`, `mdimporter`, `service`, `suite`, and `artifact`. #### target: Should Only Be Used in Select Cases Don’t use `target:` for aesthetic reasons, like removing version numbers (`app "Slack #{version}.app", target: "Slack.app"`). Use it when it makes sense functionally and document your reason clearly in the Cask, using one of the templates: [for clarity](https://github.com/Homebrew/homebrew- cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/imagemin.rb#L12); [for consistency](https://github.com/Homebrew/homebrew- cask/blob/d2a6b26df69fc28c4d84d6f5198b2b652c2f414d/Casks/devonthink-pro- office.rb#L16); [to prevent conflicts](https://github.com/Homebrew/homebrew- cask/blob/bd6dc1a64e0bdd35ba0e20789045ea023b0b6aed/Casks/flash-player- debugger.rb#L11); [due to developer suggestion](https://github.com/Homebrew/homebrew- cask/blob/ff3e9c4a6623af44b8a071027e8dcf3f4edfc6d9/Casks/kivy.rb#L12). ### Stanza: `appcast` The value of the `appcast` stanza is a string, holding the URL for an appcast which provides information on future updates. Note: The `livecheck` stanza should be preferred in most cases, as it allows casks to be updated automatically. The main casks repo only accepts submissions for stable versions of software (and [documented exceptions](acceptable-casks#but-there-is-no-stable- version)), but it still gets pull requests for unstable versions. By checking the submitted `version` against the contents of an appcast, we can better detect these invalid cases. Example: [`atom.rb`](https://github.com/Homebrew/homebrew- cask/blob/645dbb8228ec2f1f217ed1431e188687aac13ca5/Casks/atom.rb#L7) There are a few different ways the `appcast` can be determined: * If the app is distributed via GitHub releases, the `appcast` will be of the form `https://github.com///releases.atom`. Example: [`electron.rb`](https://github.com/Homebrew/homebrew-cask/blob/645dbb8228ec2f1f217ed1431e188687aac13ca5/Casks/electron.rb#L7) * If the app is distributed via GitLab releases, the `appcast` will be of the form `https://gitlab.com///-/tags?format=atom`. Example: [`grafx.rb`](https://github.com/Homebrew/homebrew-cask/blob/b22381902f9da870bb07d21b496558f283dad612/Casks/grafx.rb#L6) * The popular update framework [Sparkle](https://sparkle-project.org/) generally uses the `SUFeedURL` property in `Contents/Info.plist` inside `.app` bundles. Example: [`glyphs.rb`](https://github.com/Homebrew/homebrew-cask/blob/645dbb8228ec2f1f217ed1431e188687aac13ca5/Casks/glyphs.rb#L6) * Sourceforge projects follow the form `https://sourceforge.net/projects//rss`. A more specific page can be used as needed, pointing to a specific directory structure: `https://sourceforge.net/projects//rss?path=/`. Example: [`seashore.rb`](https://github.com/Homebrew/homebrew-cask/blob/645dbb8228ec2f1f217ed1431e188687aac13ca5/Casks/seashore.rb#L6) * An appcast can be any URL hosted by the app’s developer that changes every time a new release is out or that contains the version number of the current release (e.g. a download HTML page). Webpages that only change on new version releases are preferred, as are sites that do not contain previous version strings (i.e. avoid changelog pages if the download page contains the current version number but not older ones). Example: [`razorsql.rb`](https://github.com/Homebrew/homebrew-cask/blob/645dbb8228ec2f1f217ed1431e188687aac13ca5/Casks/razorsql.rb#L6) The [`find-appcast`](https://github.com/Homebrew/homebrew- cask/blob/HEAD/developer/bin/find-appcast) script is able to identify some of these, as well as `electron-builder` appcasts which are trickier to find by hand. Run it with `"$(brew --repository homebrew/cask)/developer/bin/find- appcast" ''`. #### Parameters key | value ---|--- `must_contain:` | a custom string for `brew audit --appcast ` to check against. Sometimes a `version` doesn’t match a string on the webpage, in which case we tweak what to search for. Example: if `version` is `6.26.1440` and the appcast’s contents only show `6.24`, the check for “is `version` in the appcast feed” will fail. With `must_contain`, the check is told to “look for this string instead of `version`”. In the example, `must_contain: version.major_minor` is saying “look for `6.24`”, making the check succeed. If no `must_contain` is given, the check considers from the beginning of the `version` string until the first character that isn’t alphanumeric or a period. Example: if `version` is `6.26b-14,40`, the check will see `6.26b`. This is so it covers most cases by default, while still allowing complex `version`s suitable for interpolation on the rest of the cask. Example of using `must_contain`: [`hwsensors.rb`](https://github.com/Homebrew/homebrew- cask/blob/87bc3860f43d5b14d0c38ae8de469d24ee7f5b2f/Casks/hwsensors.rb#L6L7) ### Stanza: `binary` In the simple case of a string argument to `binary`, the source file is linked into the `$(brew --prefix)/bin` directory (typically `/usr/local/bin`) on installation. For example (from [operadriver.rb](https://github.com/Homebrew/homebrew- cask/blob/60531a2812005dd5f17dc92f3ce7419af3c5d019/Casks/operadriver.rb#L11)): binary "operadriver" creates a symlink to: $(brew --prefix)/bin/operadriver from a source file such as: /usr/local/Caskroom/operadriver/0.2.2/operadriver A binary (or multiple) can also be contained in an application bundle: app "Atom.app" binary "#{appdir}/Atom.app/Contents/Resources/app/apm/bin/apm" You can rename the target which appears in your binaries directory by adding a `target:` key to `binary`: binary "#{appdir}/Atom.app/Contents/Resources/app/atom.sh", target: "atom" Behaviour and usage of `target:` is the same as with `app`. However, for `binary` the select cases don’t apply as rigidly. It’s fine to take extra liberties with `target:` to be consistent with other command-line tools, like [changing case](https://github.com/Homebrew/homebrew- cask/blob/9ad93b833961f1d969505bc6bdb1c2ad4e58a433/Casks/openscad.rb#L12), [removing an extension](https://github.com/Homebrew/homebrew- cask/blob/c443d4f5c6864538efe5bb1ecf662565a5ffb438/Casks/filebot.rb#L13), or [cleaning up the name](https://github.com/Homebrew/homebrew- cask/blob/146917cbcc679648de6b0bccff4e9b43fce0e6c8/Casks/minishift.rb#L13). ### Stanza: `caveats` Sometimes there are particularities with the installation of a piece of software that cannot or should not be handled programmatically by Homebrew Cask. In those instances, `caveats` is the way to inform the user. Information in `caveats` is displayed when a cask is invoked with either `install` or `info`. To avoid flooding users with too many messages (thus desensitising them to the important ones), `caveats` should be used sparingly and exclusively for installation-related matters. If you’re not sure a `caveat` you find pertinent is installation-related or not, ask a maintainer. As a general rule, if your case isn’t already covered in our comprehensive `caveats Mini-DSL`, it’s unlikely to be accepted. #### caveats as a String When `caveats` is a string, it is evaluated at compile time. The following methods are available for interpolation if `caveats` is placed in its customary position at the end of the Cask: method | description ---|--- `token` | the Cask token `version` | the Cask version `homepage` | the Cask homepage `caskroom_path` | the containing directory for this Cask, typically `/usr/local/Caskroom/` (only available with block form) `staged_path` | the staged location for this Cask, including version number: `/usr/local/Caskroom//` (only available with block form) Example: caveats "Using #{token} is hazardous to your health." #### caveats as a Block When `caveats` is a Ruby block, evaluation is deferred until install time. Within a block you may refer to the `@cask` instance variable, and invoke any method available on `@cask`. #### caveats Mini-DSL There is a mini-DSL available within `caveats` blocks. The following methods may be called to generate standard warning messages: method | description ---|--- `path_environment_variable "path"` | users should make sure `path` is in their `$PATH` environment variable. `zsh_path_helper "path"` | zsh users must take additional steps to make sure `path` is in their `$PATH` environment variable. `depends_on_java "version"` | users should make sure they have the specified version of java installed. `version` can be exact (e.g. `6`), a minimum (e.g. `7+`), or omitted (when any version works). `logout` | users should log out and log back in to complete installation. `reboot` | users should reboot to complete installation. `files_in_usr_local` | the Cask installs files to `/usr/local`, which may confuse Homebrew. `discontinued` | all software development has been officially discontinued upstream. `free_license "web_page"` | users may get an official license to use the software at `web_page`. `kext` | users may need to enable their kexts in System Preferences → Security & Privacy → General. `unsigned_accessibility` | users will need to re-enable the app on each update in System Preferences → Security & Privacy → Privacy as it is unsigned. `license "web_page"` | software has a usage license at `web_page`. Example: caveats do path_environment_variable "/usr/texbin" end ### Stanza: `conflicts_with` `conflicts_with` is used to declare conflicts that keep a Cask from installing or working correctly. #### conflicts_with cask The value should be another Cask token. Example use: [`wireshark`](https://github.com/Homebrew/homebrew- cask/blob/903493e09cf33b845e7cf497ecf9cfc9709087ee/Casks/wireshark.rb#L10), which conflicts with `wireshark-chmodbpf`. conflicts_with cask: "wireshark-chmodbpf" #### conflicts_with formula Note: `conflicts_with formula:` is a stub and is not yet functional. The value should be another formula name. Example use: [`macvim`](https://github.com/Homebrew/homebrew- cask/blob/84b90afd7b571e581f8a48d4bdf9c7bb24ebff3b/Casks/macvim.rb#L10), which conflicts with the `macvim` formula. conflicts_with formula: "macvim" ### Stanza: `depends_on` `depends_on` is used to declare dependencies and requirements for a Cask. `depends_on` is not consulted until `install` is attempted. #### depends_on cask The value should be another Cask token, needed by the current Cask. Example use: [`cellery`](https://github.com/Homebrew/homebrew- cask/blob/4002df8f6bca93ed6eb40494995fcfa038cf99bf/Casks/cellery.rb#L11) depends on OSXFUSE: depends_on cask: "osxfuse" #### depends_on formula The value should name a Homebrew Formula needed by the Cask. Example use: some distributions are contained in archive formats such as `7z` which are not supported by stock Apple tools. For these cases, a more capable archive reader may be pulled in at install time by declaring a dependency on the Homebrew Formula `unar`: depends_on formula: "unar" #### depends_on macos ##### Requiring an Exact macOS Release The value for `depends_on macos:` may be a symbol or an array of symbols, listing the exact compatible macOS releases. The available values for macOS releases are: symbol | corresponding release ---|--- `:el_capitan` | `10.11` `:sierra` | `10.12` `:high_sierra` | `10.13` `:mojave` | `10.14` `:catalina` | `10.15` `:big_sur` | `11.0` `:monterey` | `12.0` Only major releases are covered (version numbers containing a single dot). The symbol form is used for readability. The following are all valid ways to enumerate the exact macOS release requirements for a Cask: depends_on macos: :big_sur depends_on macos: [ :catalina, :big_sur, ] ##### Setting a Minimum macOS Release `depends_on macos:` can also accept a string starting with a comparison operator such as `>=`, followed by an macOS release in the form above. The following is a valid expression meaning “at least macOS Big Sur (11.0)”: depends_on macos: ">= :big_sur" A comparison expression cannot be combined with any other form of `depends_on macos:`. #### depends_on arch The value for `depends_on arch:` may be a symbol or an array of symbols, listing the hardware compatibility requirements for a Cask. The requirement is satisfied at install time if any one of multiple `arch:` value matches the user’s hardware. The available symbols for hardware are: symbol | meaning ---|--- `:x86_64` | 64-bit Intel `:intel` | 64-bit Intel `:arm64` | Apple Silicon The following are all valid expressions: depends_on arch: :intel depends_on arch: :x86_64 # same meaning as above depends_on arch: [:x86_64] # same meaning as above depends_on arch: :arm64 #### All depends_on Keys key | description ---|--- `formula:` | a Homebrew Formula `cask:` | a Cask token `macos:` | a symbol, string, array, or comparison expression defining macOS release requirements `arch:` | a symbol or array defining hardware requirements `java:` | _stub - not yet functional_ ### Stanza: `desc` `desc` accepts a single-line UTF-8 string containing a short description of the software. It’s used to help with searchability and disambiguation, thus it must concisely describe what the software does (or what you can accomplish with it). `desc` is not for app slogans! Vendors’ descriptions tend to be filled with generic adjectives such as “modern” and “lightweight”. Those are meaningless marketing fluff (do you ever see apps proudly describing themselves as outdated and bulky?) which must the deleted. It’s fine to use the information on the software’s website as a starting point, but it will require editing in almost all cases. #### Dos and Don’ts * **Do** start with an uppercase letter. - desc "sound and music editor" + desc "Sound and music editor" * **Do** be brief, i.e. use less than 80 characters. - desc "Sound and music editor which comes with effects, instruments, sounds and all kinds of creative features" + desc "Sound and music editor" * **Do** describe what the software does or is: - desc "Development of musical ideas made easy" + desc "Sound and music editor" * **Do not** include the platform. Casks only work on macOS, so this is redundant information. - desc "Sound and music editor for macOS" + desc "Sound and music editor" * **Do not** include the Cask’s name. - desc "Ableton Live is a sound and music editor" + desc "Sound and music editor" * **Do not** include the vendor. This should be added to the Cask’s name instead. - desc "Sound and music editor made by Ableton" + desc "Sound and music editor" * **Do not** add user pronouns. - desc "Edit your music files" + desc "Sound and music editor" * **Do not** use empty marketing jargon. - desc "Beautiful and powerful modern sound and music editor" + desc "Sound and music editor" ### Stanza: `\*flight` #### Evaluation of Blocks is Always Deferred The Ruby blocks defined by `preflight`, `postflight`, `uninstall_preflight`, and `uninstall_postflight` are not evaluated until install time or uninstall time. Within a block, you may refer to the `@cask` instance variable, and invoke any method available on `@cask`. #### *flight Mini-DSL There is a mini-DSL available within these blocks. The following methods may be called to perform standard tasks: method | availability | description ---|---|--- `set_ownership(paths)` | `preflight`, `postflight`, `uninstall_preflight` | set user and group ownership of `paths`. Example: [`unifi-controller.rb`](https://github.com/Homebrew/homebrew-cask/blob/8a452a41707af6a661049da6254571090fac5418/Casks/unifi-controller.rb#L13) `set_permissions(paths, permissions_str)` | `preflight`, `postflight`, `uninstall_preflight` | set permissions in `paths` to `permissions_str`. Example: [`docker-machine.rb`](https://github.com/Homebrew/homebrew-cask/blob/8a452a41707af6a661049da6254571090fac5418/Casks/docker-machine.rb#L16) `set_ownership(paths)` defaults user ownership to the current user and group ownership to `staff`. These can be changed by passing in extra options: `set_ownership(paths, user: 'user', group: 'group')`. ### Stanza: `installer` This stanza must always be accompanied by `uninstall`. The `installer` stanza takes a series of key-value pairs, the first key of which must be `manual:` or `script:`. #### installer manual `installer manual:` takes a single string value, describing a GUI installer which must be run by the user at a later time. The path may be absolute, or relative to the Cask. Example (from [nutstore.rb](https://github.com/Homebrew/homebrew- cask/blob/249ec31048591308e63e50f79dae01d2f933cccf/Casks/nutstore.rb#L9)): installer manual: "Nutstore Installer.app" #### installer script `installer script:` introduces a series of key-value pairs describing a command which will automate completion of the install. **It should never be used for interactive installations.** The form is similar to `uninstall script:`: key | value ---|--- `executable:` | path to an install script to be run `args:` | array of arguments to the install script `input:` | array of lines of input to be sent to `stdin` of the script `must_succeed:` | set to `false` if the script is allowed to fail `sudo:` | set to `true` if the script needs `sudo` The path may be absolute, or relative to the Cask. Example (from [miniforge.rb](https://github.com/Homebrew/homebrew- cask/blob/ed2033fb3578376c3ee58a2cb459ef96fa6eb37d/Casks/miniforge.rb#L15L18)): installer script: { executable: "Miniforge3-#{version}-MacOSX-x86_64.sh", args: ["-b", "-p", "#{caskroom_path}/base"], } If the `installer script:` does not require any of the key-values it can point directly to the path of the install script: installer script: "#{staged_path}/install.sh" ### Stanza: `language` The `language` stanza can match [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language codes, regional identifiers ([ISO 3166-1 Alpha 2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)) and script codes ([ISO 15924](https://en.wikipedia.org/wiki/ISO_15924)), or a combination thereof. US English should always be used as the default language: language "zh", "CN" do "zh_CN" end language "de" do "de_DE" end language "en-GB" do "en_GB" end language "en", default: true do "en_US" end Note that the following are not the same: language "en", "GB" do # matches all locales containing "en" or "GB" end language "en-GB" do # matches only locales containing "en" and "GB" end The return value of the matching `language` block can be accessed by simply calling `language`. homepage "https://example.org/#{language}" Examples: [Firefox](https://github.com/Homebrew/homebrew- cask/blob/306b8fbd9502036f1ca742f70c569d8677b62403/Casks/firefox.rb#L4L74), [Battle.net](https://github.com/Homebrew/homebrew- cask/blob/306b8fbd9502036f1ca742f70c569d8677b62403/Casks/battle-net.rb#L5L17) #### Installation To install a cask in a specific language, you can pass the `--language=` option to `brew install`: brew install firefox --language=it ### Stanza: `livecheck` The `livecheck` stanza is used to automatically fetch the latest version of a cask from changelogs, release notes, appcasts, etc. See also: [`brew livecheck` reference](brew-livecheck) Every `livecheck` block must contain a `url`, which can either be a string or a symbol pointing to other URLs in the cask (`:url` or `:homepage`). Additionally, a `livecheck` should specify which `strategy` should be used to extract the version: `strategy` | Description ---|--- `:header_match` | extract version from HTTP headers (e.g. `Location` or `Content-Disposition`) `:page_match` | extract version from page contents `:sparkle` | extract version from Sparkle appcast contents Here is a basic example, extracting a simple version from a page: livecheck do url "https://example.org/my-app/download" strategy :page_match regex(%r{href=.*?/MyApp-(\d+(?:\.\d+)*)\.zip}i) end If the download URL is present on the homepage, we can use a symbol instead of a string: livecheck do url :homepage strategy :page_match regex(%r{href=.*?/MyApp-(\d+(?:\.\d+)*)\.zip}i) end The `header_match` strategy will try parsing a version from the filename (in the `Content-Disposition` header) and the final URL (in the `Location` header). If that doesn’t work, a `regex` can be specified, e.g.: strategy :header_match regex(/MyApp-(\d+(?:\.\d+)*)\.zip/i) If the version depends on multiple header fields, a block can be specified, e.g. strategy :header_match do |headers| v = headers["content-disposition"][/MyApp-(\d+(?:\.\d+)*)\.zip/i, 1] id = headers["location"][%r{/(\d+)/download$}i, 1] next if v.blank? || id.blank? "#{v},#{id}" end Similarly, the `:page_match` strategy can also be used for more complex versions by specifying a block: strategy :page_match do |page| match = page.match(%r{href=.*?/(\d+)/MyApp-(\d+(?:\.\d+)*)\.zip}i) next if match.blank? "#{match[2]},#{match[1]}" end ### Stanza: `name` `name` accepts a UTF-8 string defining the name of the software, including capitalization and punctuation. It is used to help with searchability and disambiguation. Unlike the token, which is simplified and reduced to a limited set of characters, the `name` stanza can include the proper capitalization, spacing and punctuation to match the official name of the software. For disambiguation purposes, it is recommended to spell out the name of the application, and including the vendor name if necessary. A good example is [`pycharm- ce`](https://github.com/Homebrew/homebrew- cask/blob/fc05c0353aebb28e40db72faba04b82ca832d11a/Casks/pycharm-ce.rb#L6-L7), whose name is spelled out as `Jetbrains PyCharm Community Edition`, even though it is likely never referenced as such anywhere. Additional details about the software can be provided in the desc stanza. The `name` stanza can be repeated multiple times if there are useful alternative names. The first instance should use the Latin alphabet. For example, see the [`cave-story`](https://github.com/Homebrew/homebrew- cask/blob/0fe48607f5656e4f1de58c6884945378b7e6f960/Casks/cave-story.rb#L7-L9) cask, whose original name does not use the Latin alphabet. ### Stanza: `pkg` This stanza must always be accompanied by `uninstall` The first argument to the `pkg` stanza should be a relative path to the `.pkg` file to be installed. For example: pkg "Unity.pkg" Subsequent arguments to `pkg` are key/value pairs which modify the install process. Currently supported keys are `allow_untrusted:` and `choices:`. #### `pkg allow_untrusted:` `pkg allow_untrusted: true` can be used to install the `.pkg` with an untrusted certificate passing `-allowUntrusted` to `/usr/sbin/installer`. This option is not permitted in official Homebrew Cask taps, it is only provided for use in third-party taps or local Casks. Example ([alinof-timer.rb](https://github.com/Homebrew/homebrew- cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/alinof- timer.rb#L10)): pkg "AlinofTimer.pkg", allow_untrusted: true #### `pkg choices:` `pkg choices:` can be used to override `.pkg`’s default install options via `-applyChoiceChangesXML`. It uses a deserialized version of the `choiceChanges` property list (refer to the `CHOICE CHANGES FILE` section of the `installer` manual page by running `man -P 'less --pattern "^CHOICE CHANGES FILE"' installer`). Running the macOS command: installer -showChoicesXML -pkg '/path/to/my.pkg' will output an XML which you can use to extract the `choices:` values, as well as their equivalents to the GUI options. See [this pull request for wireshark- chmodbpf](https://github.com/Homebrew/homebrew-cask/pull/26997) and [this one for wine-staging](https://github.com/Homebrew/homebrew-cask/pull/27937) for some examples of the procedure. Example ([wireshark-chmodbpf.rb](https://github.com/Homebrew/homebrew- cask/blob/f95b8a8306b91fe9da7908b842f4a5fa80f7afe0/Casks/wireshark- chmodbpf.rb#L9-L26)): pkg "Wireshark #{version} Intel 64.pkg", choices: [ { "choiceIdentifier" => "wireshark", "choiceAttribute" => "selected", "attributeSetting" => 0, }, { "choiceIdentifier" => "chmodbpf", "choiceAttribute" => "selected", "attributeSetting" => 1, }, { "choiceIdentifier" => "cli", "choiceAttribute" => "selected", "attributeSetting" => 0, }, ] Example ([wine-staging.rb](https://github.com/Homebrew/homebrew- cask/blob/51b65f6a5a25a7f79af4d372e1a0bf1dc3849251/Casks/wine- staging.rb#L11-L18)): pkg "winehq-staging-#{version}.pkg", choices: [ { "choiceIdentifier" => "choice3", "choiceAttribute" => "selected", "attributeSetting" => 1, }, ] ### Stanza: `sha256` #### Calculating the SHA256 The `sha256` value is usually calculated by the command: shasum --algorithm 256 #### Special Value `:no_check` The special value `sha256 :no_check` is used to turn off SHA checking whenever checksumming is impractical due to the upstream configuration. `version :latest` requires `sha256 :no_check`, and this pairing is common. However, `sha256 :no_check` does not require `version :latest`. We use a checksum whenever possible. ### Stanza: `suite` Some distributions provide a suite of multiple applications, or an application with required data, to be installed together in a subdirectory of `/Applications`. For these Casks, use the `suite` stanza to define the directory containing the application suite. Example (from [sketchup.rb](https://github.com/Homebrew/homebrew- cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/sketchup.rb#L12)): suite "SketchUp 2016" The value of `suite` is never an `.app` bundle, but a plain directory. ### Stanza: `uninstall` > If you cannot design a working `uninstall` stanza, please submit your cask > anyway. The maintainers can help you write an `uninstall` stanza, just ask! #### `uninstall pkgutil:` Is The Easiest and Most Useful `pkgutil:` is the easiest and most useful `uninstall` directive. See Uninstall Key pkgutil:. #### `uninstall` Is Required for Casks That Install a pkg or installer manual For most Casks, uninstall actions are determined automatically, and an explicit `uninstall` stanza is not needed. However, a Cask which uses the `pkg` or `installer manual:` stanzas will **not** know how to uninstall correctly unless an `uninstall` stanza is given. So, while the Cask DSL does not enforce the requirement, it is much better for end-users if every `pkg` and `installer manual:` has a corresponding `uninstall`. The `uninstall` stanza is available for non-`pkg` Casks, and is useful for a few corner cases. However, the documentation below concerns the typical case of using `uninstall` to define procedures for a `pkg`. #### There Are Multiple Uninstall Techniques Since `pkg` installers can do arbitrary things, different techniques are needed to uninstall in each case. You may need to specify one, or several, of the following key/value pairs as arguments to `uninstall`. #### Summary of Keys * `early_script:` (string or hash) - like `script:`, but runs early (for special cases, best avoided) * `launchctl:` (string or array) - ids of `launchctl` jobs to remove * `quit:` (string or array) - bundle ids of running applications to quit * `signal:` (array of arrays) - signal numbers and bundle ids of running applications to send a Unix signal to (used when `quit:` does not work) * `login_item:` (string or array) - names of login items to remove * `kext:` (string or array) - bundle ids of kexts to unload from the system * `script:` (string or hash) - relative path to an uninstall script to be run via sudo; use hash if args are needed * `executable:` \- relative path to an uninstall script to be run via sudo (required for hash form) * `args:` \- array of arguments to the uninstall script * `input:` \- array of lines of input to be sent to `stdin` of the script * `must_succeed:` \- set to `false` if the script is allowed to fail * `sudo:` \- set to `true` if the script needs `sudo` * `pkgutil:` (string, regexp or array of strings and regexps) - strings or regexps matching bundle ids of packages to uninstall using `pkgutil` * `delete:` (string or array) - single-quoted, absolute paths of files or directory trees to remove. `delete:` should only be used as a last resort. `pkgutil:` is strongly preferred. * `rmdir:` (string or array) - single-quoted, absolute paths of directories to remove if empty. Works recursively. * `trash:` (string or array) - single-quoted, absolute paths of files or directory trees to move to Trash. Each `uninstall` technique is applied according to the order above. The order in which `uninstall` keys appear in the Cask file is ignored. For assistance filling in the right values for `uninstall` keys, there are several helper scripts found under `developer/bin` in the Homebrew Cask repository. Each of these scripts responds to the `-help` option with additional documentation. The easiest way to work out an `uninstall` stanza is on a system where the `pkg` is currently installed and operational. To operate on an uninstalled `pkg` file, see Working With a pkg File Manually, below. #### `uninstall` Key `pkgutil:` This is the most useful uninstall key. `pkgutil:` is often sufficient to completely uninstall a `pkg`, and is strongly preferred over `delete:`. IDs for the most recently-installed packages can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_recent_pkg_ids" `pkgutil:` also accepts a regular expression match against multiple package IDs. The regular expressions are somewhat nonstandard. To test a `pkgutil:` regular expression against currently-installed packages, use the command: "$(brew --repository homebrew/cask)/developer/bin/list_pkg_ids_by_regexp" #### List Files Associated With a pkg Id Once you know the ID for an installed package, (above), you can list all files on your system associated with that package ID using the macOS command: pkgutil --files Listing the associated files can help you assess whether the package included any `launchctl` jobs or kernel extensions (kexts). #### `uninstall` Key `launchctl:` IDs for currently loaded `launchctl` jobs can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_loaded_launchjob_ids" IDs for all installed `launchctl` jobs can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_installed_launchjob_ids" #### `uninstall` Key `quit:` Bundle IDs for currently running Applications can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_running_app_ids" Bundle IDs inside an Application bundle on disk can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_ids_in_app" '/path/to/application.app' #### `uninstall` Key `signal:` `signal:` should only be needed in the rare case that a process does not respond to `quit:`. Bundle IDs for `signal:` targets may be obtained as for `quit:`. The value for `signal:` is an array-of-arrays, with each cell containing two elements: the desired Unix signal followed by the corresponding bundle ID. The Unix signal may be given in numeric or string form (see the `kill` man page for more details). The elements of the `signal:` array are applied in order, only if there is an existing process associated the bundle ID, and stopping when that process terminates. A bundle ID may be repeated to send more than one signal to the same process. It is better to use the least-severe signals which are sufficient to stop a process. The `KILL` signal in particular can have unwanted side-effects. An example, with commonly-used signals in ascending order of severity: uninstall signal: [ ["TERM", "fr.madrau.switchresx.daemon"], ["QUIT", "fr.madrau.switchresx.daemon"], ["INT", "fr.madrau.switchresx.daemon"], ["HUP", "fr.madrau.switchresx.daemon"], ["KILL", "fr.madrau.switchresx.daemon"], ] Note that when multiple running processes match the given Bundle ID, all matching processes will be signaled. Unlike `quit:` directives, Unix signals originate from the current user, not from the superuser. This is construed as a safety feature, since the superuser is capable of bringing down the system via signals. However, this inconsistency may also be considered a bug, and should be addressed in some fashion in a future version. ## `uninstall` key `login_item:` Login items associated with an Application bundle on disk can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_login_items_for_app" '/path/to/application.app' Note that you will likely need to have opened the app at least once for any login items to be present. #### `uninstall` Key `kext:` IDs for currently loaded kernel extensions can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_loaded_kext_ids" IDs inside a kext bundle you have located on disk can be listed using the command: "$(brew --repository homebrew/cask)/developer/bin/list_id_in_kext" '/path/to/name.kext' #### `uninstall` Key `script:` `uninstall script:` introduces a series of key-value pairs describing a command which will automate completion of the uninstall. Example (from gpgtools.rb): uninstall script: { executable: "#{staged_path}/Uninstall.app/Contents/Resources/GPG Suite Uninstaller.app/Contents/Resources/uninstall.sh", sudo: true, } It is important to note that, although `script:` in the above example does attempt to completely uninstall the `pkg`, it should not be used in detriment of `pkgutil:`, but as a complement when possible. #### `uninstall` Key `delete:` `delete:` should only be used as a last resort, if other `uninstall` methods are insufficient. Arguments to `uninstall delete:` should use the following basic rules: * Basic tilde expansion is performed on paths, i.e. leading `~` is expanded to the home directory. * Paths must be absolute. * Glob expansion is performed using the [standard set of characters](https://en.wikipedia.org/wiki/Glob_\(programming\)). To remove user-specific files, use the `zap` stanza. #### `uninstall` Key `trash:` `trash:` arguments follow the same rules listed above for `delete:`. #### Working With a pkg File Manually Advanced users may wish to work with a `pkg` file manually, without having the package installed. A list of files which may be installed from a `pkg` can be extracted using the command: "$(brew --repository homebrew/cask)/developer/bin/list_payload_in_pkg" '/path/to/my.pkg' Candidate application names helpful for determining the name of a Cask may be extracted from a `pkg` file using the command: "$(brew --repository homebrew/cask)/developer/bin/list_apps_in_pkg" '/path/to/my.pkg' Candidate package IDs which may be useful in a `pkgutil:` key may be extracted from a `pkg` file using the command: "$(brew --repository homebrew/cask)/developer/bin/list_ids_in_pkg" '/path/to/my.pkg' A fully manual method for finding bundle ids in a package file follows: 1. Unpack `/path/to/my.pkg` (replace with your package name) with `pkgutil --expand /path/to/my.pkg /tmp/expanded.unpkg`. 2. The unpacked package is a folder. Bundle ids are contained within files named `PackageInfo`. These files can be found with the command `find /tmp/expanded.unpkg -name PackageInfo`. 3. `PackageInfo` files are XML files, and bundle ids are found within the `identifier` attributes of `` tags that look like ``, where extraneous attributes have been snipped out and replaced with ellipses. 4. Kexts inside packages are also described in `PackageInfo` files. If any kernel extensions are present, the command `find /tmp/expanded.unpkg -name PackageInfo -print0 | xargs -0 grep -i kext` should return a `` tag with a `path` attribute that contains a `.kext` extension, for example ``. 5. Once bundle ids have been identified, the unpacked package directory can be deleted. ### Stanza: `url` #### HTTPS URLs are Preferred If available, an HTTPS URL is preferred. A plain HTTP URL should only be used in the absence of a secure alternative. #### Additional HTTP/S URL Parameters When a plain URL string is insufficient to fetch a file, additional information may be provided to the `curl`-based downloader, in the form of key/value pairs appended to `url`: key | value ---|--- `verified:` | a string repeating the beginning of `url`, for verification purposes. See below. `using:` | the symbol `:post` is the only legal value `cookies:` | a hash of cookies to be set in the download request `referer:` | a string holding the URL to set as referer in the download request `header:` | a string holding the header to set for the download request. `user_agent:` | a string holding the user agent to set for the download request. Can also be set to the symbol `:fake`, which will use a generic Browser-like user agent string. We prefer `:fake` when the server does not require a specific user agent. `data:` | a hash of parameters to be set in the POST request Example of using `cookies:`: [java.rb](https://github.com/Homebrew/homebrew- cask/blob/472930df191d66747a57d5c96c0d00511d56e21b/Casks/java.rb#L5-L8) Example of using `referer:`: [rrootage.rb](https://github.com/Homebrew/homebrew- cask/blob/312ae841f1f1b2ec07f4d88b7dfdd7fbdf8d4f94/Casks/rrootage.rb#L5) Example of using `header:`: [issue-325182724](https://github.com/Homebrew/brew/pull/6545#issue-325182724) #### When URL and Homepage Domains Differ, Add `verified:` When the domains of `url` and `homepage` differ, the discrepancy should be documented with the `verified:` parameter, repeating the smallest possible portion of the URL that uniquely identifies the app or vendor, excluding the protocol. Example: [`shotcut.rb`](https://github.com/Homebrew/homebrew- cask/blob/08733296b49c59c58b6beeada59ed4207cef60c3/Casks/shotcut.rb#L5L6). This must be added so a user auditing the cask knows the URL was verified by the Homebrew Cask team as the one provided by the vendor, even though it may look unofficial. It is our responsibility as Homebrew Cask maintainers to verify both the `url` and `homepage` information when first added (or subsequently modified, apart from versioning). The parameter doesn’t mean you should trust the source blindly, but we only approve casks in which users can easily verify its authenticity with basic means, such as checking the official homepage or public repository. Occasionally, slightly more elaborate techniques may be used, such as inspecting an `appcast` we established as official. Cases where such quick verifications aren’t possible (e.g. when the download URL is behind a registration wall) are [treated in a stricter manner](acceptable- casks#unofficial-vendorless-and-walled-builds). #### Difficulty Finding a URL Web browsers may obscure the direct `url` download location for a variety of reasons. Homebrew Cask supplies a script which can read extended file attributes to extract the actual source URL for most files downloaded by a browser on macOS. The script usually emits multiple candidate URLs; you may have to test each of them: $(brew --repository homebrew/cask)/developer/bin/list_url_attributes_on_file #### Subversion URLs In rare cases, a distribution may not be available over ordinary HTTP/S. Subversion URLs are also supported, and can be specified by appending the following key/value pairs to `url`: key | value ---|--- `using:` | the symbol `:svn` is the only legal value `revision:` | a string identifying the subversion revision to download `trust_cert:` | set to `true` to automatically trust the certificate presented by the server (avoiding an interactive prompt) #### SourceForge/OSDN URLs SourceForge and OSDN (formerly `SourceForge.JP`) projects are common ways to distribute binaries, but they provide many different styles of URLs to get to the goods. We prefer URLs of this format: https://downloads.sourceforge.net//. Or, if it’s from [OSDN](https://osdn.jp/): http://.osdn.jp///. `` is typically of the form `dl` or `.dl`. If these formats are not available, and the application is macOS-exclusive (otherwise a command-line download defaults to the Windows version) we prefer the use of this format: https://sourceforge.net/projects//files/latest/download #### Some Providers Block Command-line Downloads Some hosting providers actively block command-line HTTP clients. Such URLs cannot be used in Casks. Other providers may use URLs that change periodically, or even on each visit (example: FossHub). While some cases could be circumvented, they tend to occur when the vendor is actively trying to prevent automated downloads, so we prefer to not add those casks to the main repository. #### Using a Block to Defer Code Execution Some casks—notably nightlies—have versioned download URLs but are updated so often that they become impractical to keep current with the usual process. For those, we want to dynamically determine `url`. ##### The Problem In theory, one can write arbitrary Ruby code right in the Cask definition to fetch and construct a disposable URL. However, this typically involves an HTTP round trip to a landing site, which may take a long time. Because of the way Homebrew Cask loads and parses Casks, it is not acceptable that such expensive operations be performed directly in the body of a Cask definition. ##### Writing the Block Similar to the `preflight`, `postflight`, `uninstall_preflight`, and `uninstall_postflight` blocks, the `url` stanza offers an optional _block syntax_ : url "https://handbrake.fr/nightly.php" do |page| file_path = page[/href=["']?([^"' >]*Handbrake[._-][^"' >]+\.dmg)["' >]/i, 1] file_path ? URI.join(page.url, file_path) : nil end You can also nest `url do` blocks inside `url do` blocks to follow a chain of URLs. The block is only evaluated when needed, for example on download time or when auditing a Cask. Inside a block, you may safely do things such as HTTP/S requests that may take a long time to execute. You may also refer to the `@cask` instance variable, and invoke any method available on `@cask`. The block will be called immediately before downloading; its result value will be assumed to be a `String` (or a pair of a `String` and `Hash` containing parameters) and subsequently used as a download URL. You can use the `url` stanza with either a direct argument or a block but not with both. Example for using the block syntax: [vlc- nightly.rb](https://github.com/Homebrew/homebrew-cask- versions/blob/2bf0f13dd49d263ebec0ca56e58ad8458633f789/Casks/vlc- nightly.rb#L5L10) ##### Mixing Additional URL Parameters With the Block Syntax In rare cases, you might need to set URL parameters like `cookies` or `referer` while also using the block syntax. This is possible by returning a two-element array as a block result. The first element of the array must be the download URL; the second element must be a `Hash` containing the parameters. ### Stanza: `version` `version`, while related to the app’s own versioning, doesn’t have to follow it exactly. It is common to change it slightly so it can be [interpolated](https://en.wikipedia.org/wiki/String_interpolation#Ruby_/_Crystal) in other stanzas, usually in `url` to create a Cask that only needs `version` and `sha256` changes when updated. This can be taken further, when needed, with [ruby String methods](https://ruby-doc.org/core/String.html). For example: Instead of version "1.2.3" url "https://example.com/file-version-123.dmg" We can use version "1.2.3" url "https://example.com/file-version-#{version.delete('.')}.dmg" We can also leverage the power of regular expressions. So instead of version "1.2.3build4" url "https://example.com/1.2.3/file-version-1.2.3build4.dmg" We can use version "1.2.3build4" url "https://example.com/#{version.sub(%r{build\d+}, '')}/file-version-#{version}.dmg" #### version :latest The special value `:latest` is used on casks which: 1. `url` doesn’t contain a version. 2. Having a correct value to `version` is too difficult or impractical, even with our automated systems. Example: [spotify.rb](https://github.com/Homebrew/homebrew- cask/blob/f56e8ba057687690e26a6502623aa9476ff4ac0e/Casks/spotify.rb#L2) #### version methods The examples above can become hard to read, however. Since many of these changes are common, we provide a number of helpers to clearly interpret otherwise obtuse cases: Method | Input | Output ---|---|--- `major` | `1.2.3-a45,ccdd88` | `1` `minor` | `1.2.3-a45,ccdd88` | `2` `patch` | `1.2.3-a45,ccdd88` | `3-a45` `major_minor` | `1.2.3-a45,ccdd88` | `1.2` `major_minor_patch` | `1.2.3-a45,ccdd88` | `1.2.3-a45` `minor_patch` | `1.2.3-a45,ccdd88` | `2.3-a45` `before_comma` | `1.2.3-a45,ccdd88` | `1.2.3-a45` `after_comma` | `1.2.3-a45,ccdd88` | `ccdd88` `dots_to_hyphens` | `1.2.3-a45,ccdd88` | `1-2-3-a45,ccdd88` `no_dots` | `1.2.3-a45,ccdd88` | `123-a45,ccdd88` Similar to `dots_to_hyphens`, we provide all logical permutations of `{dots,hyphens,underscores}_to_{dots,hyphens,underscores}`. The same applies to `no_dots` in the form of `no_{dots,hyphens,underscores}`, with an extra `no_dividers` that applies all of those at once. Finally, there is `csv` that returns an array of comma-separated values. `csv`, `before_comma` and `after_comma` are extra special to allow for otherwise complex cases, and should be used sparingly. There should be no more than two of `,` per `version`. ### Stanza: `zap` #### `zap` Stanza Purpose The `zap` stanza describes a more complete uninstallation of files associated with a Cask. The `zap` procedures will never be performed by default, but only if the user uses `--zap` on `uninstall`: brew uninstall --zap firefox `zap` stanzas may remove: * Preference files and caches stored within the user’s `~/Library` directory. * Shared resources such as application updaters. Since shared resources may be removed, other applications may be affected by `brew uninstall --zap`. Understanding that is the responsibility of the end user. `zap` stanzas should not remove: * Files created by the user directly. Appending `--force` to the command will allow you to perform these actions even if the Cask is no longer installed: brew uninstall --zap --force firefox #### `zap` Stanza Syntax The form of `zap` stanza follows the `uninstall` stanza. All of the same directives are available. The `trash:` key is preferred over `delete:`. Example: [dropbox.rb](https://github.com/Homebrew/homebrew- cask/blob/31cd96cc0e00dab1bff74d622e32d816bafd1f6f/Casks/dropbox.rb#L17-L35) #### `zap` Creation The simplest method is to use [@nrlquaker’s CreateZap](https://github.com/nrlquaker/homebrew-createzap), which can automatically generate the stanza. In a few instances it may fail to pick up anything and manual creation may be required. Manual creation can be facilitated with: * Some of the developer tools are already available in Homebrew Cask. * `sudo find / -iname "**"` * An uninstaller tool such as [AppCleaner](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/appcleaner.rb). * Inspecting the usual suspects, i.e. `/Library/{'Application Support',LaunchAgents,LaunchDaemons,Frameworks,Logs,Preferences,PrivilegedHelperTools}` and `~/Library/{'Application Support',Caches,Containers,LaunchAgents,Logs,Preferences,'Saved Application State'}`. * * * ## Token reference This section describes the algorithm implemented in the `generate_cask_token` script, and covers detailed rules and exceptions which are not needed in most cases. * Purpose * Finding the Simplified Name of the Vendor’s Distribution * Converting the Simplified Name To a Token * Cask Filenames * Cask Headers * Cask Token Examples * Tap Specific Cask Token Examples * Token Overlap ## Purpose Software vendors are often inconsistent with their naming. By enforcing strict naming conventions we aim to: * Prevent duplicate submissions * Minimize renaming events * Unambiguously boil down the name of the software into a unique identifier Details of software names and brands will inevitably be lost in the conversion to a minimal token. To capture the vendor’s full name for a distribution, use the `name` within a Cask. `name` accepts an unrestricted UTF-8 string. ## Finding the Simplified Name of the Vendor’s Distribution ### Simplified Names of Apps * Start with the exact name of the Application bundle as it appears on disk, such as `Google Chrome.app`. * If the name uses letters outside A-Z, convert it to ASCII as described in Converting to ASCII. * Remove `.app` from the end. * Remove from the end: the string “app”, if the vendor styles the name like “Software App.app”. Exception: when “app” is an inseparable part of the name, without which the name would be inherently nonsensical, as in [whatsapp.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/whatsapp.rb). * Remove from the end: version numbers or incremental release designations such as “alpha”, “beta”, or “release candidate”. Strings which distinguish different capabilities or codebases such as “Community Edition” are currently accepted. Exception: when a number is not an incremental release counter, but a differentiator for a different product from a different vendor, as in [kdiff3.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/kdiff3.rb). * If the version number is arranged to occur in the middle of the App name, it should also be removed. * Remove from the end: “Launcher”, “Quick Launcher”. * Remove from the end: strings such as “Desktop”, “for Desktop”. * Remove from the end: strings such as “Mac”, “for Mac”, “for OS X”, “macOS”, “for macOS”. These terms are generally added to ported software such as “MAME OS X.app”. Exception: when the software is not a port, and “Mac” is an inseparable part of the name, without which the name would be inherently nonsensical, as in [PlayOnMac.app](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/playonmac.rb). * Remove from the end: hardware designations such as “for x86”, “32-bit”, “ppc”. * Remove from the end: software framework names such as “Cocoa”, “Qt”, “Gtk”, “Wx”, “Java”, “Oracle JVM”, etc. Exception: the framework is the product being Casked. * Remove from the end: localization strings such as “en-US”. * If the result of that process is a generic term, such as “Macintosh Installer”, try prepending the name of the vendor or developer, followed by a hyphen. If that doesn’t work, then just create the best name you can, based on the vendor’s web page. * If the result conflicts with the name of an existing Cask, make yours unique by prepending the name of the vendor or developer, followed by a hyphen. Example: [unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/unison.rb) and [panic-unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/panic-unison.rb). * Inevitably, there are a small number of exceptions not covered by the rules. Don’t hesitate to [use the forum](https://github.com/orgs/Homebrew/discussions) if you have a problem. ### Converting to ASCII * If the vendor provides an English localization string, that is preferred. Here are the places it may be found, in order of preference: * `CFBundleDisplayName` in the main `Info.plist` file of the app bundle * `CFBundleName` in the main `Info.plist` file of the app bundle * `CFBundleDisplayName` in `InfoPlist.strings` of an `en.lproj` localization directory * `CFBundleName` in `InfoPlist.strings` of an `en.lproj` localization directory * `CFBundleDisplayName` in `InfoPlist.strings` of an `English.lproj` localization directory * `CFBundleName` in `InfoPlist.strings` of an `English.lproj` localization directory * When there is no vendor localization string, romanize the name by transliteration or decomposition. * As a last resort, translate the name of the app bundle into English. ### Simplified Names of `pkg`-based Installers * The Simplified Name of a `pkg` may be more tricky to determine than that of an App. If a `pkg` installs an App, then use that App name with the rules above. If not, just create the best name you can, based on the vendor’s web page. ### Simplified Names of non-App Software * Currently, rules for generating a token are not well-defined for Preference Panes, QuickLook plugins, and several other types of software installable by Homebrew Cask. Just create the best name you can, based on the filename on disk or the vendor’s web page. Watch out for duplicates. Non-app tokens should become more standardized in the future. ## Converting the Simplified Name To a Token The token is the primary identifier for a package in our project. It’s the unique string users refer to when operating on the Cask. To convert the App’s Simplified Name (above) to a token: * Convert all letters to lower case. * Expand the `+` symbol into a separated English word: `-plus-`. * Expand the `@` symbol into a separated English word: `-at-`. * Spaces become hyphens. * Underscores become hyphens. * Middots/Interpuncts become hyphens. * Hyphens stay hyphens. * Digits stay digits. * Delete any character which is not alphanumeric or a hyphen. * Collapse a series of multiple hyphens into one hyphen. * Delete a leading or trailing hyphen. ## Cask Filenames Casks are stored in a Ruby file named after the token, with the file extension `.rb`. ## Cask Headers The token is also given in the header line for each Cask. ## Cask Token Examples These illustrate most of the rules for generating a token: App Name on Disk | Simplified App Name | Cask Token | Filename ---|---|---|--- `Audio Hijack Pro.app` | Audio Hijack Pro | audio-hijack-pro | `audio-hijack-pro.rb` `VLC.app` | VLC | vlc | `vlc.rb` `BetterTouchTool.app` | BetterTouchTool | bettertouchtool | `bettertouchtool.rb` `LPK25 Editor.app` | LPK25 Editor | lpk25-editor | `lpk25-editor.rb` `Sublime Text 2.app` | Sublime Text | sublime-text | `sublime-text.rb` ## Tap Specific Cask Token Examples Cask taps have naming conventions specific to each tap. [Homebrew/cask-versions](https://github.com/Homebrew/homebrew-cask- versions/blob/HEAD/CONTRIBUTING.md#naming-versions-casks) [Homebrew/cask-fonts](https://github.com/Homebrew/homebrew-cask- fonts/blob/HEAD/CONTRIBUTING.md#naming-font-casks) [Homebrew/cask-drivers](https://github.com/Homebrew/homebrew-cask- drivers/blob/HEAD/CONTRIBUTING.md#naming-driver-casks) # Special Affixes A few situations require a prefix or suffix to be added to the token. ## Token Overlap When the token for a new Cask would otherwise conflict with the token of an already existing Cask, the nature of that overlap dictates the token (for possibly both Casks). See [Forks and Apps with Conflicting Names](acceptable- casks#forks-and-apps-with-conflicting-names) for information on how to proceed. ## Potentially Misleading Name If the token for a piece of unofficial software that interacts with a popular service would make it look official and the vendor is not authorised to use the name, [a prefix must be added](acceptable-casks#forks-and-apps-with- conflicting-names) for disambiguation. In cases where the prefix is ambiguous and would make the app appear official, the `-unofficial` suffix may be used. # MD5 and SHA-1 Deprecation In early 2015 Homebrew started the process of deprecating _SHA1_ for package integrity verification. Since then formulae under the Homebrew organisation have been migrated to use _SHA256_ for verification; this includes both source packages and our precompiled packages (bottles). Homebrew has since stopped supporting _SHA1_ and _MD5_ entirely. _MD5_ checksums were removed from core formulae in 2012 and as of April 2015 installing a formula verified by _MD5_ is actively blocked. We removed _SHA1_ support in **November 2016** , 21 months after we started warning people to move away from it for verification. This is enforced in the same way _MD5_ is, by blocking the installation of that individual formula until the checksum is migrated. This means custom taps, local custom formulae, etc. need to be migrated to use _SHA256_ before you can install them. # Common Issues This is a list of commonly encountered problems, known issues, and their solutions. ## Running `brew` ### `brew` complains about absence of “Command Line Tools” You need to have the Xcode Command Line Utilities installed (and updated): run `xcode-select --install` in the terminal. ### Ruby: `bad interpreter: /usr/bin/ruby^M: no such file or directory` You cloned with `git`, and your Git configuration is set to use Windows line endings. See this page on [configuring Git to handle line endings](https://docs.github.com/en/get-started/getting-started-with- git/configuring-git-to-handle-line-endings). ### Ruby: `bad interpreter: /usr/bin/ruby` You don’t have a `/usr/bin/ruby` or it is not executable. It’s not recommended to let this persist; you’d be surprised how many `.app`s, tools and scripts expect your macOS-provided files and directories to be _unmodified_ since macOS was installed. ### `brew update` complains about untracked working tree files After running `brew update`, you receive a Git error warning about untracked files or local changes that would be overwritten by a checkout or merge, followed by a list of files inside your Homebrew installation. This is caused by an old bug in in the `update` code that has long since been fixed. However, the nature of the bug requires that you do the following: cd "$(brew --repository)" git reset --hard FETCH_HEAD If `brew doctor` still complains about uncommitted modifications, also run this command: cd "$(brew --repository)/Library" git clean -fd ### `launchctl` refuses to load launchd plist files When trying to load a plist file with `launchctl`, you receive an error that resembles either: Bug: launchctl.c:2325 (23930):13: (dbfd = open(g_job_overrides_db_path, [...] launch_msg(): Socket is not connected or: Could not open job overrides database at: /private/var/db/launchd.db/com.apple.launchd/overrides.plist: 13: Permission denied launch_msg(): Socket is not connected These are likely due to one of four issues: 1. You are using iTerm. The solution is to use Terminal.app when interacting with `launchctl`. 2. You are using a terminal multiplexer such as `tmux` or `screen`. You should interact with `launchctl` from a separate Terminal.app shell. 3. You are attempting to run `launchctl` while logged in remotely. You should enable screen sharing on the remote machine and issue the command using Terminal.app running on that machine. 4. You are `su`‘ed as a different user. ### `brew upgrade` errors out When running `brew upgrade`, you see something like this: Error: undefined method `include?' for nil:NilClass Please report this bug: https://docs.brew.sh/Troubleshooting /usr/local/Library/Homebrew/formula.rb:393:in `canonical_name' /usr/local/Library/Homebrew/formula.rb:425:in `factory' /usr/local/Library/Contributions/examples/brew-upgrade.rb:7 /usr/local/Library/Contributions/examples/brew-upgrade.rb:7:in `map' /usr/local/Library/Contributions/examples/brew-upgrade.rb:7 /usr/local/bin/brew:46:in `require' /usr/local/bin/brew:46:in `require?' /usr/local/bin/brew:79 This happens because an old version of the upgrade command is hanging around for some reason. The fix: cd "$(brew --repository)/Library/Contributions/examples" git clean -n # if this doesn't list anything that you want to keep, then git clean -f # this will remove untracked files ### Python: `easy-install.pth` cannot be linked Warning: Could not link . Unlinking... Error: The `brew link` step did not complete successfully The formula built, but is not symlinked into /usr/local You can try again using `brew link ' Possible conflicting files are: /usr/local/lib/python2.7/site-packages/site.py /usr/local/lib/python2.7/site-packages/easy-install.pth ==> Could not symlink file: /homebrew/Cellar///lib/python2.7/site-packages/site.py Target /usr/local/lib/python2.7/site-packages/site.py already exists. You may need to delete it. To force the link and overwrite all other conflicting files, do: brew link --overwrite formula_name To list all files that would be deleted: brew link --overwrite --dry-run formula_name Don’t follow the advice here but fix by using `Language::Python.setup_install_args` in the formula as described in [Python for Formula Authors](python-for-formula-authors). ## Upgrading macOS Upgrading macOS can cause errors like the following: * `dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.54.dylib` * `configure: error: Cannot find libz` Following a macOS upgrade it may be necessary to reinstall the Xcode Command Line Tools and then `brew upgrade` all installed formulae: xcode-select --install brew upgrade ## Cask - cURL error First, let’s tackle a common problem: do you have a `.curlrc` file? Check with `ls -A ~ | grep .curlrc` (if you get a result, the file exists). Those are a frequent cause of issues of this nature. Before anything else, remove that file and try again. If it now works, do not open an issue. Incompatible `.curlrc` configurations must be fixed on your side. If, however, you do not have a `.curlrc` or removing it did not work, let’s see if the issue is upstream: 1. Go to the vendor’s website (`brew home `). 2. Find the download link for the app and click on it. ### If the download works The cask is outdated. Let’s fix it: 1. Look around the app’s website and find out what the latest version is. It will likely be expressed in the URL used to download it. 2. Take a look at the cask’s version (`brew cat `) and verify it is indeed outdated. If the app’s version is `:latest`, it means the `url` itself is outdated. It will need to be changed to the new one. Help us by [submitting a fix](https://github.com/Homebrew/homebrew- cask/blob/HEAD/CONTRIBUTING.md#updating-a-cask). If you get stumped, [open an issue](https://github.com/Homebrew/homebrew- cask/issues/new?template=01_bug_report.md) explaining your steps so far and where you’re having trouble. ### If the download does not work The issue isn’t in any way related to Homebrew Cask, but with the vendor or your connection. Start by diagnosing your connection (try to download other casks, go around the web). If the problem is with your connection, try a website like [Ask Different](https://apple.stackexchange.com/) to ask for advice. If you’re sure the issue is not with your connection, contact the app’s vendor and let them know their link is down, so they can fix it. **Do not open an issue.** ## Cask - checksum does not match First, check if the problem was with your download. Delete the downloaded file (its location will be pointed out in the error message) and try again. If the problem persists, the cask must be outdated. It’ll likely need a new version, but it’s possible the version has remained the same (happens occasionally when the vendor updates the app in place). 1. Go to the vendor’s website (`brew home `). 2. Find out what the latest version is. It may be expressed in the URL used to download it. 3. Take a look at the cask’s version (`brew info `) and verify it is indeed outdated. If it is: Help us by [submitting a fix](https://github.com/Homebrew/homebrew- cask/blob/HEAD/CONTRIBUTING.md#updating-a-cask). If you get stumped, [open an issue](https://github.com/Homebrew/homebrew- cask/issues/new?template=01_bug_report.md) explaining your steps so far and where you’re having trouble. ## Cask - permission denied In this case, it’s likely your user account has no admin rights so you don’t have permissions to write to `/Applications` (which is the default). You can use [`--appdir`](https://github.com/Homebrew/homebrew- cask/blob/HEAD/USAGE.md#options) to choose where to install your applications. If `--appdir` doesn’t fix the issue or you do have write permissions to `/Applications`, verify you’re the owner of the `Caskroom` directory by running `ls -dl "$(brew --prefix)/Caskroom"` and checking the third field. If you are not the owner, fix it with `sudo chown -R "$(whoami)" "$(brew --prefix)/Caskroom"`. If you are, the problem may lie in the app bundle itself. Some app bundles don’t have certain permissions that are necessary for us to move them to the appropriate location. You may check such permissions with `ls -ls `. If you see something like `dr-xr-xr-x` at the start of the output, that may be the cause. To fix it, we change the app bundle’s permission to allow us to move it, and then set it back to what it was (in case the developer set those permissions deliberately). See [`litecoin`](https://github.com/Homebrew/homebrew- cask/blob/0cde71f1fea8ad62d6ec4732fcf35ac0c52d8792/Casks/litecoin.rb#L14L20) for an example of such a cask. Help us by [submitting a fix](https://github.com/Homebrew/homebrew- cask/blob/HEAD/CONTRIBUTING.md#updating-a-cask). If you get stumped, [open an issue](https://github.com/Homebrew/homebrew- cask/issues/new?template=01_bug_report.md) explaining your steps so far and where you’re having trouble. ## Cask - source is not there First, you need to identify which artifact is not being handled correctly anymore. It’s explicit in the error message: if it says `It seems the App source…'` the problem is [`app`](cask-cookbook#stanza-app). The pattern is the same across [all artifacts](cask-cookbook#at-least-one-artifact-stanza-is- also-required). Fixing this error is typically easy, and requires only a bit of time on your part. Start by downloading the package for the cask: `brew fetch `. The last line of output will inform you of the location of the download. Navigate there and manually unpack it. As an example, lets say the structure inside the archive is as follows: . ├─ Files/SomeApp.app ├─ Files/script.sh └─ README.md Now, let’s look at the cask (`brew cat `): (…) app "SomeApp.app" (…) The cask was expecting `SomeApp.app` to be in the top directory of the archive (see how it says simply `SomeApp.app`) but the developer changed it to inside a `Files` directory. All we have to do is update that line of the cask to follow the new structure: `app 'Files/SomeApp.app'`. Note that occasionally the app’s name changes completely (from `SomeApp.app` to `OtherApp.app`, let’s say). In these instances, the filename of the cask itself, as well as its token, must also change. Consult the [`token reference`](cask-cookbook#token-reference) for complete instructions on the new name. Help us by [submitting a fix](https://github.com/Homebrew/homebrew- cask/blob/HEAD/CONTRIBUTING.md#updating-a-cask). If you get stumped, [open an issue](https://github.com/Homebrew/homebrew- cask/issues/new?template=01_bug_report.md) explaining your steps so far and where you’re having trouble. ## Cask - wrong number of arguments Make sure the issue really lies with your macOS version. To do so, try to install the software manually. If it is incompatible with your macOS version, it will tell you. In that case, there is nothing we can do to help you install the software, but we can add a [`depends_on macos:`](cask-cookbook#depends_on- macos) stanza to prevent the cask from trying to install on incompatible macOS versions. Help us by [submitting a fix](https://github.com/Homebrew/homebrew- cask/blob/HEAD/CONTRIBUTING.md#updating-a-cask). If you get stumped, [open an issue](https://github.com/Homebrew/homebrew- cask/issues/new?template=01_bug_report.md) explaining your steps so far and where you’re having trouble. ## Other local issues If your Homebrew installation gets messed up (and fixing the issues found by `brew doctor` doesn’t solve the problem), reinstalling Homebrew may help to reset to a normal state. To easily reinstall Homebrew, use [Homebrew Bundle](https://github.com/Homebrew/homebrew-bundle) to automatically restore your installed formulae and casks. To do so, run `brew bundle dump`, [uninstall](faq#how-do-i-uninstall-homebrew), [reinstall](installation) and run `brew bundle install`. # Creating a Homebrew Issue First, check to make sure your issue is not listed in the [FAQ](faq) or [Common Issues](common-issues) and can’t otherwise be resolved with the information in the [Tips and Tricks](tips-n'-tricks) documentation. Next, go through the steps in the [Troubleshooting guide](troubleshooting). If the preceding steps did not help, it may be appropriate to submit an issue. This can be done by navigating to the relevant repository, clicking the “Issues” link, and clicking on the “New issue” button. When creating an issue, make sure you use the provided template, as it’s important in helping others to understand and potentially triage your issue efficiently. # Custom GCC and Cross Compilers Homebrew depends on having an up-to-date version of Xcode because it comes with specific versions of build tools, e.g. `clang`. Installing a custom version of GCC or Autotools into your `PATH` has the potential to break lots of compiles so we prefer the Apple- or Homebrew-provided compilers. Cross compilers based on GCC will typically be “keg-only” and therefore not linked into your `PATH` by default, or be prefixed with the target architecture, again to avoid conflicting with Apple or Homebrew compilers. Rather than merging formulae for either of these cases at this time, we’re listing them on this page. If you come up with a formula for a new version of GCC or cross-compiler suite, please link to it here. * Homebrew provides a `gcc` formula for use with Xcode 4.2+. * Homebrew provides older GCC formulae, e.g. `gcc@7`. * Homebrew provides some cross-compilers and toolchains, but these are named to avoid clashing with the default tools, e.g. `i686-elf-gcc`, `x86_64-elf-gcc`. * Homebrew provides LLVM’s Clang, which is bundled with the `llvm` formula. * [RISC-V](https://github.com/riscv/homebrew-riscv) provides the RISC-V toolchain including binutils and GCC. # Deprecating, Disabling, and Removing Formulae There are many reasons why formulae may be deprecated, disabled, or removed. This document explains the differences between each method as well as explaining when one method should be used over another. ## Overview This general rule of thumb can be followed: * `deprecate!` should be used for formulae that _should_ no longer be used. * `disable!` should be used for formulae that _cannot_ be used. * Formulae that are no longer acceptable in homebrew/core or have been disabled for over a year should be removed. ## Deprecation If a user attempts to install a deprecated formula, they will be shown a warning message but the install will proceed. A formula should be deprecated to indicate to users that the formula should not be used and will be disabled in the future. Deprecated formulae should be maintained by the Homebrew maintainers so they can still build from source and their bottles continue to work (even if unmaintained upstream). If this is not possible, they should be disabled. The most common reasons for deprecation are when the upstream project is deprecated, unmaintained, or archived. Formulae with dependents may be deprecated only if at least one of the following are true: * its dependents are all deprecated * the formula does not build on any of our supported macOS versions and on Linux * the formula has outstanding CVEs To deprecate a formula, add a `deprecate!` call. This call should include a deprecation date (in the ISO 8601 format) and a deprecation reason: deprecate! date: "YYYY-MM-DD", because: :reason The `date` parameter should be set to the date that the project or version became (or will become) deprecated. If there is no clear date but the formula needs to be deprecated, use today’s date. If the `date` parameter is set to a date in the future, the formula will not become deprecated until that date. This can be useful if the upstream developers have indicated a date where the project or version will stop being supported. The `because` parameter can be a preset reason (using a symbol) or a custom reason. See the Deprecate and Disable Reasons section below for more details about the `because` parameter. ## Disabling If a user attempts to install a disabled formula, they will be shown an error message and the install will fail. A formula should be disabled to indicate to users that the formula cannot be used and will be removed in the future. Disabled formulae may no longer build from source or have working bottles. The most common reasons for disabling a formula are: * it cannot be built from source (meaning no bottles can be built) * it has been deprecated for a long time * the upstream repository has been removed * the project has no license Formulae should not be disabled without a deprecation period of at least three months unless the circumstances are exceptional (e.g. the formula does not build on any supported macOS version or Linux). Popular formulae should have longer deprecation periods. The popularity of a formula should be based on our analytics data. **Note: disabled formulae in homebrew/core will be automatically removed one year after their disable date** To disable a formula, add a `disable!` call. This call should include a deprecation date (in the ISO 8601 format) and a deprecation reason: disable! date: "YYYY-MM-DD", because: :reason The `date` parameter should be set to the date that the reason for disabling came into effect. If there is no clear date but the formula needs to be disabled, use today’s date. If the `date` parameter is set to a date in the future, the formula will be deprecated until that date (on which the formula will become disabled). The `because` parameter can be a preset reason (using a symbol) or a custom reason. See the Deprecate and Disable Reasons section below for more details about the `because` parameter. ## Removal A formula should be removed if it does not meet our criteria for [acceptable formulae](acceptable-formulae) or [versioned formulae](versions), has a non- open-source license, or has been disabled for over a year. ## Deprecate and Disable Reasons When a formula is deprecated or disabled, a reason explaining the action must be provided. There are two ways to indicate the reason. The preferred way is to use a pre- existing symbol to indicate the reason. The available symbols are listed below and can be found in the [`DeprecateDisable` module](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/deprecate_disable.rb): * `:does_not_build`: the formula cannot be built from source * `:no_license`: the formula does not have a license * `:repo_archived`: the upstream repository has been archived * `:repo_removed`: the upstream repository has been removed * `:unmaintained`: the project appears to be abandoned * `:unsupported`: Homebrew’s application of the software is not supported by the upstream developers (e.g. upstream only supports macOS versions prior to 10.14) * `:deprecated_upstream`: the project is deprecated upstream * `:versioned_formula`: the formula is a versioned formula These reasons can be specified by their symbols (the comments show the message that will be displayed to users): # Warning: has been deprecated because it is deprecated upstream! deprecate! date: "2020-01-01", because: :deprecated_upstream # Error: has been disabled because it does not build! disable! date: "2020-01-01", because: :does_not_build If these pre-existing reasons do not fit, a custom reason can be specified. These reasons should be written to fit into the sentence ` has been deprecated/disabled because it !`. A well-worded example of a custom reason would be: # Warning: has been deprecated because it fetches unversioned dependencies at runtime! deprecate! date: "2020-01-01", because: "fetches unversioned dependencies at runtime" A poorly-worded example of a custom reason would be: # Error: has been disabled because it invalid license! disable! date: "2020-01-01", because: "invalid license" # Diagram Guidelines ## Preferred file format For complex diagrams, use the `.drawio.svg` format. Files with the `.drawio.svg` extension are SVG files with embedded [draw.io](https://www.diagrams.net/) source code. Using that format lends itself to a developer-friendly workflow: it is valid SVG, plays well with `git diff` and can be edited in lock-step using various online and offline flavours of draw.io. If you use VS Code, you can use an [extension](https://marketplace.visualstudio.com/items?itemName=hediet.vscode- drawio) for draw.io integration. Files in the `.drawio.svg` format can be processed offline. ## Embedding a diagram into Markdown To embed a `.drawio.svg` file into Markdown, use the same syntax as for any image. Example: `![My diagram](my-diagram.drawio.svg)` Mind that GitHub doesn’t allow styling in Markdown documents. Where styling is allowed (e.g. in the exported brew.sh version of the documentation), always set a background colour of `white` for the diagram. That’s the colour draw.io assumes, and keeps the diagram easy to read in dark mode without further customization. You can use the CSS selector `img[src$=".drawio.svg"]` for styling. ## Example Example for an SVG image embedded into Markdown: ![Example diagram: Managing Pull Requests](/assets/img/docs/managing-pull-requests.drawio.svg) Result: Example for styling (where allowed): img[src$=".drawio.svg"] { background-color: white; margin-bottom: 20px; padding: 5%; width: 90%; } @media (prefers-color-scheme: dark) { img[src$=".drawio.svg"] { filter: invert(85%); -webkit-filter: invert(85%); } } # External Commands Homebrew, like Git, supports _external commands_. This lets you create new commands that can be run like: brew mycommand --option1 --option3 without modifying Homebrew’s internals. ## Command types External commands come in two flavours: Ruby commands and shell scripts. In both cases, the command file should be executable (`chmod +x`) and live somewhere in your `PATH`. External commands can be added to a tap to allow easy distribution. See below for more details. ### Ruby commands An external command `extcmd` implemented as a Ruby command should be named `brew-extcmd.rb`. The command is executed by doing a `require` on the full pathname. As the command is `require`d, it has full access to the Homebrew “environment”, i.e. all global variables and modules that any internal command has access to. Be wary of using Homebrew internals; they may change at any time without warning. The command may `Kernel.exit` with a status code if it needs to; if it doesn’t explicitly exit then Homebrew will return `0`. ### Other executable scripts An executable script for a command named `extcmd` should be named `brew- extcmd`. The script itself can use any suitable shebang (`#!`) line, so an external script can be written in Bash, Ruby, or even Python. Unlike the ruby commands this file must not end with a language-specific suffix (`.sh`, or `.py`). This file will be run via `exec` with some Homebrew variables set as environment variables, and passed any additional command-line arguments. Variable | Description ---|--- `HOMEBREW_CACHE` | Where Homebrew caches downloaded tarballs to, by default `~/Library/Caches/Homebrew`. `HOMEBREW_PREFIX` | Where Homebrew installs software. `/usr/local` by default for macOS Intel, `/opt/homebrew` for Apple Silicon and `/home/linuxbrew/.linuxbrew` for Linux. `HOMEBREW_CELLAR` | The location of the Homebrew Cellar, where software is staged. This will be `HOMEBREW_PREFIX/Cellar` if that directory exists, or `HOMEBREW_REPOSITORY/Cellar` otherwise. `HOMEBREW_LIBRARY_PATH` | The directory containing Homebrew’s own application code. `HOMEBREW_REPOSITORY` | The Git repository directory (i.e. where Homebrew’s `.git` directory lives). Usually either the same as `HOMEBREW_PREFIX` or a `Homebrew` subdirectory. ## Providing `--help` All internal and external Homebrew commands can provide styled `--help` output by using Homebrew’s [argument parser](https://rubydoc.brew.sh/Homebrew/CLI/Parser.html), as seen in the [`brew services` command](https://github.com/Homebrew/homebrew- services/blob/HEAD/cmd/services.rb); or by including lines starting with `#:` (a comment then `:` character in both Bash and Ruby), as seen in the [header of `update.sh`](https://github.com/Homebrew/brew/blob/cf7def0c68903814c6b4e04a55fe8f3cb3f5605e/Library/Homebrew/cmd/update.sh#L1-L10), which is printed with `brew update --help`. ## Unofficial external commands These commands have been contributed by Homebrew users but are not included in the main Homebrew organisation, nor are they installed by the installer script. You can install them manually, as outlined above. Note they are largely untested, and as always, be careful about running untested code on your machine. ### brew-gem Install any `gem` package into a self-contained Homebrew Cellar location: Note this can also be installed with `brew install brew-gem`. ## External commands in taps External commands can be hosted in a [tap](taps) to allow users to easily install and use them. See [How to Create and Maintain a Tap](how-to-create- and-maintain-a-tap) for more details about creating and maintaining a tap. External commands should be added to a `cmd` directory in the tap. An external command `extcmd` implemented as a Ruby command should live in `cmd/extcmd.rb` (don’t forget to `chmod +x`). To easily use Homebrew’s argument parser, replicate the following Ruby template for external commands (replacing all instances of `foo` with the name of the command): # frozen_string_literal: true module Homebrew module_function def foo_args Homebrew::CLI::Parser.new do description <<~EOS Do something. Place a description here. EOS switch "-f", "--force", description: "Force doing something in the command." flag "--file=", description: "Specify a file to do something with in the command." comma_array "--names", description: "Add a list of names to the command." named_args [:formula, :cask], min: 1 end end def foo args = foo_args.parse something if args.force? something_else if args.file == "file.txt" end end Using the above will generate appropriate help text: $ brew foo --help Usage: brew foo [options] formula|cask [...] Do something. Place a description here. -f, --force Force doing something in the command. --file Specify a file to do something with in the command. --names Add a list of names to the command. -d, --debug Display any debugging information. -q, --quiet Make some output more quiet. -v, --verbose Make some output more verbose. -h, --help Show this message. The usage string is automatically generated based on the specified number and type of named arguments (see below for more details on specifying named arguments). The generated usage string can be overridden by passing the correct usage string to the `usage_banner` method (placed just before the `description` method). See the [`brew tap` command](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/cmd/tap.rb) for an example. Use the `named_args` method to specify the type and number of named arguments that are expected. Pass either a symbol to indicate the type of argument expected, an array of symbols to indicate that multiple types should be expected, or an array of strings to specify which specific options should be expected (see the [`brew analytics` command](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/cmd/analytics.rb) for an example of this). Pass an integer to the `number`, `min`, or `max` parameter of `named_args` to specify the number of named arguments that are expected. See the following examples: # Accept no named args named_args :none # Accept any number (including none) of formula arguments named_args :formula # Accept exactly one of the specified options as an argument named_args %w[state off on], number: 1 # Accept at least one argument that is either a formula or a cask named_args [:formula, :cask], min: 1 # Accept no more than one argument that is a tap named_args :tap, max: 1 # Accept between one and two named args named_args min: 1, max: 2 Named arguments can be accessed by calling `args.named`. Check out the internal [commands](https://github.com/Homebrew/brew/tree/HEAD/Library/Homebrew/cmd) and [developer commands](https://github.com/Homebrew/brew/tree/HEAD/Library/Homebrew/dev-cmd) for more usage examples. # FAQ ## Is there a glossary of terms around? The Formula Cookbook has a list of [Homebrew terminology](formula- cookbook#homebrew-terminology). ## How do I update my local packages? First update all package definitions (formulae) and Homebrew itself: brew update You can now list which of your installed packages (kegs) are outdated with: brew outdated Upgrade everything with: brew upgrade Or upgrade a specific formula with: brew upgrade ## How do I stop certain formulae from being updated? To stop something from being updated/upgraded: brew pin To allow that formulae to update again: brew unpin Note that pinned, outdated formulae that another formula depends on need to be upgraded when required, as we do not allow formulae to be built against outdated versions. If this is not desired, you can instead use `brew extract` to [maintain your own copy of the formula in a tap](how-to-create-and- maintain-a-tap). ## How do I uninstall Homebrew? To uninstall Homebrew, run the [uninstall script from the Homebrew/install repository](https://github.com/homebrew/install#uninstall-homebrew). ## How do I keep old versions of a formula when upgrading? Homebrew automatically uninstalls old versions of each formula that is upgraded with `brew upgrade`, and periodically performs additional cleanup every 30 days. To **disable** automatic `brew cleanup`: export HOMEBREW_NO_INSTALL_CLEANUP=1 To disable automatic `brew cleanup` only for formulae `foo` and `bar`: export HOMEBREW_NO_CLEANUP_FORMULAE=foo,bar When automatic `brew cleanup` is disabled, if you uninstall a formula, it will only remove the latest version you have installed. It will not remove all versions of the formula that you may have installed in the past. Homebrew will continue to attempt to install the newest version it knows about when you run `brew upgrade`. This can be surprising. In this case, to remove a formula entirely, you may run `brew uninstall --force `. Be careful as this is a destructive operation. ## Why does `brew upgrade ` or `brew install ` also upgrade a bunch of other stuff? Homebrew doesn’t support arbitrary mixing and matching of formula versions, so everything a formula depends on, and everything that depends on it in turn, needs to be upgraded to the latest version as that’s the only combination of formulae we test. As a consequence any given `upgrade` or `install` command can upgrade many other (seemingly unrelated) formulae, especially if something important like `python` or `openssl` also needed an upgrade. ## Where does stuff get downloaded? brew --cache Which is usually: `~/Library/Caches/Homebrew` ## My Mac `.app`s don’t find Homebrew utilities! GUI apps on macOS don’t have Homebrew’s prefix in their `PATH` by default. If you’re on Mountain Lion or later, you can fix this by running `sudo launchctl config user path "$(brew --prefix)/bin:${PATH}"` and then rebooting, as documented in `man launchctl`. Note that this sets the `launchctl` `PATH` for _all users_. For earlier versions of macOS, see [this page](https://developer.apple.com/legacy/library/qa/qa1067/_index.html). ## How do I contribute to Homebrew? Read our [contribution guidelines](https://github.com/Homebrew/brew/blob/HEAD/CONTRIBUTING.md#contributing- to-homebrew). ## Why do you compile everything? Homebrew provides pre-built binary packages for many formulae. These are referred to as [bottles](bottles) and are available at . If available, bottled binaries will be used by default except under the following conditions: * The `--build-from-source` option is invoked. * No bottle is available for the machine’s currently running OS version. (Bottles for macOS are generated only for supported macOS versions.) * Homebrew is installed to a prefix other than the default (although some bottles support this). * Formula options were passed to the install command. For example, `brew install ` will try to find a bottled binary, but `brew install --with-foo ` will trigger a source build. We aim to bottle everything. ## How do I get a formula from someone else’s pull request? brew install hub brew update cd "$(brew --repository homebrew/core)" hub fetch github_username hub pr checkout pull_request_number ## Why should I install Homebrew in the default location? Homebrew’s pre-built binary packages (known as [bottles](bottles)) of many formulae can only be used if you install in the default installation prefix, otherwise they have to be built from source. Building from source takes a long time, is prone to failure, and is not supported. The default prefix is: * `/usr/local` for macOS on Intel, * `/opt/homebrew` for macOS on Apple Silicon/ARM, and * `/home/linuxbrew/.linuxbrew` for Linux. Do yourself a favour and install to the default prefix so that you can use our pre-built binary packages. _Pick another prefix at your peril!_ ## Why is the default installation prefix `/opt/homebrew` on Apple Silicon? The prefix `/opt/homebrew` was chosen to allow installations in `/opt/homebrew` for Apple Silicon and `/usr/local` for Rosetta 2 to coexist and use bottles. ## Why is the default installation prefix `/home/linuxbrew/.linuxbrew` on Linux? The prefix `/home/linuxbrew/.linuxbrew` was chosen so that users without admin access can still benefit from precompiled binaries via a `linuxbrew` role account. If you do not yourself have admin privileges, consider asking your admin staff to create a `linuxbrew` role account for you with home directory `/home/linuxbrew`. ## Why does Homebrew say sudo is bad? **tl;dr** Sudo is dangerous, and you installed TextMate.app without sudo anyway. Homebrew refuses to work using sudo. You should only ever sudo a tool you trust. Of course, you can trust Homebrew 😉 — but do you trust the multi-megabyte Makefile that Homebrew runs? Developers often understand C++ far better than they understand `make` syntax. It’s too high a risk to sudo such stuff. It could modify (or upload) any files on your system. And indeed, we’ve seen some build scripts try to modify `/usr` even when the prefix was specified as something else entirely. We use the macOS sandbox to stop this but this doesn’t work when run as the `root` user (which also has read and write access to almost everything on the system). Did you `chown root /Applications/TextMate.app`? Probably not. So is it that important to `chown root wget`? If you need to run Homebrew in a multi-user environment, consider creating a separate user account specifically for use of Homebrew. ## Why isn’t a particular command documented? If it’s not in [`man brew`](manpage), it’s probably an [external command](external-commands) with documentation available using `--help`. ## Why haven’t you merged my pull request? If all maintainer feedback has been addressed and all tests are passing, bump it with a “bump” comment. Sometimes we miss requests and there are plenty of them. In the meantime, rebase your pull request so that it can be more easily merged. ## Can I edit formulae myself? Yes! It’s easy! Just `brew edit `. You don’t have to submit modifications back to `homebrew/core`, just edit the formula to what you personally need and `brew install `. As a bonus, `brew update` will merge your changes with upstream so you can still keep the formula up-to-date **with** your personal modifications! ## Can I make new formulae? Yes! It’s easy! Just `brew create URL`. Homebrew will then open the formula in `EDITOR` so you can edit it, but it probably already installs; try it: `brew install `. If you encounter any issues, run the command with the `--debug` switch like so: `brew install --debug `, which drops you into a debugging shell. If you want your new formula to be part of `homebrew/core` or want to learn more about writing formulae, then please read the [Formula Cookbook](formula- cookbook). ## Why was a formula deleted or disabled? Use `brew log ` to find out! Likely because it had [unresolved issues](acceptable-formulae) and/or [our analytics](https://formulae.brew.sh/analytics/) indicated it was not widely used. For disabled and deprecated formulae, running `brew info ` will also provide an explanation. ## Homebrew is a poor name, it’s too generic; why was it chosen? Homebrew’s creator @mxcl wasn’t too concerned with the beer theme and didn’t consider that the project may actually prove popular. By the time Max realised that it was popular, it was too late. However, today, the first Google hit for “homebrew” is not beer related 😉 ## What does “keg-only” mean? It means the formula is installed only into the Cellar and is not linked into the default prefix. This means most tools will not find it. You can see why a formula was installed as keg-only, and instructions for including it in your `PATH`, by running `brew info `. You can [modify a tool’s build configuration](how-to-build-software-outside- homebrew-with-homebrew-keg-only-dependencies) to find keg-only dependencies. Or, you can link in the formula if you need to with `brew link `, though this can cause unexpected behaviour if you are shadowing macOS software. ## How can I specify different configure arguments for a formula? `brew edit ` and edit the formula directly. Currently there is no other way to do this. ## Why can’t I open a Mac app from an “unidentified developer”? Chances are that certain apps will give you a popup message like this: This is a [security feature from Apple](https://support.apple.com/en- us/HT202491). The single most important thing to know is that **you can allow individual apps to be exempt from this feature.** This allows the app to run while the rest of the system remains under protection. **Always leave system-wide protection enabled,** and disable it only for specific apps as needed. If you’re sure you want to trust the app, you can disable protection for it by right-clicking its icon and choosing _Open_ : In the resulting dialog, click the _Open_ button to have macOS permanently allow the app to run on this Mac. **Don’t do this unless you’re sure you trust the app.** Alternatively, you may provide the [`--no-quarantine` flag](https://github.com/Homebrew/homebrew-cask/blob/HEAD/USAGE.md#options) at install time to not add this feature to a specific app. ## Why aren’t some apps included during `brew upgrade`? After running `brew upgrade`, you may notice some casks you think should be upgrading, aren’t. As you’re likely aware, a lot of macOS software can upgrade itself: That could cause conflicts when used in tandem with Homebrew Cask’s `upgrade` mechanism. When software uses its built-in mechanisms to upgrade itself, it happens without Homebrew Cask’s knowledge, causing both versions get out of sync. If you were to then upgrade through Homebrew Cask while we have a lower version of the software on record, you’d get a downgrade. There are a few ideas to fix this problem: * Try to prevent the software’s automated updates. It wouldn’t be a universal solution and may cause it to break. Most software on Homebrew Cask is closed-source, so we’d be guessing. This is also why pinning casks to a version isn’t available. * Try to extract the installed software’s version and compare it to the cask, deciding what to do at that time. It’d be a complicated solution that would break other parts of our methodology, such as using versions to interpolate `url` values (a definite win for maintainability). This solution also isn’t universal, as many software developers are inconsistent in their versioning schemes (and app bundles are meant to have two version strings) and it doesn’t work for all types of software we support. So we let software be. Anything installed with Homebrew Cask should behave the same as if it were installed manually. But since we also want to support software that doesn’t self-upgrade, we add [`auto_updates true`](https://github.com/Homebrew/homebrew- cask/blob/62c0495b254845a481dacac6ea7c8005e27a3fb0/Casks/alfred.rb#L10) to casks for software that does, which excludes them from `brew upgrade`. Casks which use [`version :latest`](cask-cookbook#version-latest) are also excluded, because we have no way to track their installed version. It helps to ask the developers of such software to provide versioned releases (i.e. include the version in the path of the download `url`). If you still want to force software to be upgraded via Homebrew Cask, you can reference it specifically in the `upgrade` command: brew upgrade Or use the `--greedy` flag: brew upgrade --greedy Refer to the `upgrade` section of the [`brew` manual page](manpage) for more details. # Formula Cookbook A _formula_ is a package definition written in Ruby. It can be created with `brew create ` where `` is a zip or tarball, installed with `brew install `, and debugged with `brew install --debug --verbose `. Formulae use the [Formula API](https://rubydoc.brew.sh/Formula) which provides various Homebrew-specific helpers. ## Homebrew terminology Term | Description | Example ---|---|--- **Formula** | The package definition | `/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/foo.rb` **Keg** | The installation prefix of a **Formula** | `/usr/local/Cellar/foo/0.1` **Keg-only** | A **Formula** is **Keg-only** if it is not linked into the Homebrew prefix | The [`openjdk` formula](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openjdk.rb) **opt prefix** | A symlink to the active version of a **Keg** | `/usr/local/opt/foo ` **Cellar** | All **Kegs** are installed here | `/usr/local/Cellar` **Tap** | A Git repository of **Formulae** and/or commands | `/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core` **Bottle** | Pre-built **Keg** used instead of building from source | `qt-4.8.4.catalina.bottle.tar.gz` **Cask** | An [extension of Homebrew](https://github.com/Homebrew/homebrew-cask) to install macOS native apps | `/Applications/MacDown.app/Contents/SharedSupport/bin/macdown` **Brew Bundle** | An [extension of Homebrew](https://github.com/Homebrew/homebrew-bundle) to describe dependencies | `brew 'myservice', restart_service: true` ## An introduction Homebrew uses Git for downloading updates and contributing to the project. Homebrew installs to the `Cellar` and then symlinks some of the installation into `/usr/local` so that other programs can see what’s going on. We suggest you `brew ls` a few of the kegs in your Cellar to see how it is all arranged. Packages are installed according to their formulae, which live in `/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula`. Check out a simple one, e.g. `brew edit etl` (or [`etl`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/etl.rb)) or a more advanced one, e.g. `brew edit git` (or [`git`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/git.rb)). ## Basic instructions Make sure you run `brew update` before you start. This turns your Homebrew installation into a Git repository. Before submitting a new formula make sure your package: * meets all our [Acceptable Formulae](acceptable-formulae) requirements * isn’t already in Homebrew (check `brew search `) * isn’t already waiting to be merged (check the [issue tracker](https://github.com/Homebrew/homebrew-core/pulls)) * is still supported by upstream (i.e. doesn’t require extensive patching) * has a stable, tagged version (i.e. not just a GitHub repository with no versions) * passes all `brew audit --new-formula ` tests Before submitting a new formula make sure you read over our [contribution guidelines](https://github.com/Homebrew/brew/blob/HEAD/CONTRIBUTING.md#contributing- to-homebrew). ### Grab the URL Run `brew create` with a URL to the source tarball: brew create https://example.com/foo-0.1.tar.gz This creates `/usr/local/Homebrew/Library/Taps/homebrew/homebrew- core/Formula/foo.rb` and opens it in your `EDITOR`. It’ll look something like: class Foo < Formula desc "" homepage "" url "https://example.com/foo-0.1.tar.gz" sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7" license "" # depends_on "cmake" => :build def install # ENV.deparallelize system "./configure", "--disable-debug", "--disable-dependency-tracking", "--disable-silent-rules", "--prefix=#{prefix}" # system "cmake", ".", *std_cmake_args system "make", "install" end test do system "false" end end If `brew` said `Warning: Version cannot be determined from URL` when doing the `create` step, you’ll need to explicitly add the correct [`version`](https://rubydoc.brew.sh/Formula#version-class_method) to the formula and then save the formula. Homebrew will try to guess the formula’s name from its URL. If it fails to do so you can override this with `brew create --set-name `. ### Fill in the `homepage` **We don’t accept formulae without a[`homepage`](https://rubydoc.brew.sh/Formula#homepage%3D-class_method)!** An SSL/TLS (https) [`homepage`](https://rubydoc.brew.sh/Formula#homepage%3D-class_method) is preferred, if one is available. Try to summarise from the [`homepage`](https://rubydoc.brew.sh/Formula#homepage%3D-class_method) what the formula does in the [`desc`](https://rubydoc.brew.sh/Formula#desc%3D-class_method)ription. Note that the [`desc`](https://rubydoc.brew.sh/Formula#desc%3D-class_method)ription is automatically prepended with the formula name. ### Fill in the `license` **We don’t accept new formulae into Homebrew/homebrew-core without a[`license`](https://rubydoc.brew.sh/Formula#license-class_method)!** We only accept formulae that use a [Debian Free Software Guidelines license](https://wiki.debian.org/DFSGLicenses) or are released into the public domain following [DFSG Guidelines on Public Domain software](https://wiki.debian.org/DFSGLicenses#Public_Domain). Use the license identifier from the [SPDX License List](https://spdx.org/licenses/) e.g. `license "BSD-2-Clause"`, or use `license :public_domain` for public domain software. 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. Check out the [License Guidelines](license-guidelines) for examples of complex license expressions in Homebrew formulae. ### Check the build system brew install --interactive foo You’re now at a new prompt with the tarball extracted to a temporary sandbox. Check the package’s `README`. Does the package install with `./configure`, `cmake`, or something else? Delete the commented out `cmake` lines if the package uses `./configure`. ### Check for dependencies The `README` probably tells you about dependencies and Homebrew or macOS probably already has them. You can check for Homebrew dependencies with `brew search`. Some common dependencies that macOS comes with: * `libexpat` * `libGL` * `libiconv` * `libpcap` * `libxml2` * `python` * `ruby` There are plenty of others; check `/usr/lib` for them. We generally try not to duplicate system libraries and complicated tools in core Homebrew but we do duplicate some commonly used tools. Special exceptions are OpenSSL and LibreSSL. Things that use either _should_ be built using Homebrew’s shipped equivalent and our Brew Test Bot’s post- install `audit` will warn if it detects you haven’t done this. Homebrew’s OpenSSL is [`keg_only`](https://rubydoc.brew.sh/Formula#keg_only- class_method) to avoid conflicting with the system so sometimes formulae need to have environment variables set or special configuration flags passed to locate our OpenSSL. You can see this mechanism in the [`clamav`](https://github.com/Homebrew/homebrew- core/blob/89c4574ef1a6d15e92196637ff315a0a4bb3e289/Formula/clamav.rb#L37) formula. Usually this is unnecessary because Homebrew sets up our [build environment](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/extend/ENV/super.rb) to favour finding [`keg_only`](https://rubydoc.brew.sh/Formula#keg_only- class_method) formulae first. **Important:** `$(brew --prefix)/bin` is NOT on the `PATH` during formula installation. If you have dependencies at build time, you must specify them and `brew` will add them to the `PATH` or create a [`Requirement`](https://rubydoc.brew.sh/Requirement). ### Specifying other formulae as dependencies class Foo < Formula depends_on "pkg-config" depends_on "jpeg" depends_on "readline" => :recommended depends_on "gtk+" => :optional depends_on "httpd" => [:build, :test] depends_on :xcode => "9.3" end A String (e.g. `"jpeg"`) specifies a formula dependency. A Symbol (e.g. `:xcode`) specifies a [`Requirement`](https://rubydoc.brew.sh/Requirement) which can be fulfilled by one or more formulae, casks or other system-wide installed software (e.g. Xcode). A Hash (e.g. `=>`) adds information to a dependency. Given a String or Symbol, the value can be one or more of the following values: * `:build` means that dependency is a build-time only dependency so it can be skipped when installing from a bottle or when listing missing dependencies using `brew missing`. * `:test` means that dependency is only required when running `brew test`. * `:optional` generates an implicit `with-foo` option for the formula. This means that, given `depends_on "foo" => :optional`, the user must pass `--with-foo` in order to use the dependency. * `:recommended` generates an implicit `without-foo` option, meaning that the dependency is enabled by default and the user must pass `--without-foo` to disable this dependency. The default description can be overridden using the normal option syntax (in this case, the option declaration must precede the dependency): option "with-foo", "Compile with foo bindings" # This overrides the generated description if you want to depends_on "foo" => :optional # Generated description would otherwise be "Build with foo support" * Some [`Requirement`](https://rubydoc.brew.sh/Requirement)s can also take a string specifying their minimum version that the formula depends on. **Note:** `:optional` and `:recommended` are not allowed in Homebrew/homebrew- core as they are not tested by CI. ### Specifying conflicts with other formulae Sometimes there’s hard conflict between formulae, and it can’t be avoided or circumvented with [`keg_only`](https://rubydoc.brew.sh/Formula#keg_only- class_method). A good example formula for minor conflict is [`mbedtls`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/mbedtls.rb), which ships and compiles a “Hello World” executable. This is obviously non-essential to `mbedtls`’s functionality, and conflict with the popular GNU [`hello`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/hello.rb) formula would be overkill, so we just [remove it](https://github.com/Homebrew/homebrew- core/blob/966273060ad507fea490bd931971963de8b1a1dc/Formula/mbedtls.rb#L30-L31) during the installation process. [`pdftohtml`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/pdftohtml.rb) provides an example of a serious conflict, where both formula ship an identically-named binary that is essential to functionality, so a [`conflicts_with`](https://rubydoc.brew.sh/Formula#conflicts_with- class_method) is preferable. As a general rule, [`conflicts_with`](https://rubydoc.brew.sh/Formula#conflicts_with- class_method) should be a last-resort option. It’s a fairly blunt instrument. The syntax for a conflict that can’t be worked around is: conflicts_with "blueduck", because: "yellowduck also ships a duck binary" ### Formulae revisions In Homebrew we sometimes accept formulae updates that don’t include a version bump. These include resource updates, new patches or fixing a security issue with a formula. Occasionally, these updates require a forced-recompile of the formula itself or its dependents to either ensure formulae continue to function as expected or to close a security issue. This forced-recompile is known as a [`revision`](https://rubydoc.brew.sh/Formula#revision%3D-class_method) and is inserted underneath the [`homepage`](https://rubydoc.brew.sh/Formula#homepage%3D-class_method)/[`url`](https://rubydoc.brew.sh/Formula#url- class_method)/[`sha256`](https://rubydoc.brew.sh/Formula#sha256%3D-class_method) block. When a dependent of a formula fails against a new version of that dependency it must receive a [`revision`](https://rubydoc.brew.sh/Formula#revision%3D-class_method). An example of such failure can be seen [here](https://github.com/Homebrew/legacy- homebrew/issues/31195) and the fix [here](https://github.com/Homebrew/legacy- homebrew/pull/31207). [`revision`](https://rubydoc.brew.sh/Formula#revision%3D-class_method)s are also used for formulae that move from the system OpenSSL to the Homebrew- shipped OpenSSL without any other changes to that formula. This ensures users aren’t left exposed to the potential security issues of the outdated OpenSSL. An example of this can be seen in [this commit](https://github.com/Homebrew/homebrew- core/commit/0d4453a91923e6118983961e18d0609e9828a1a4). ### Version scheme changes Sometimes formulae have version schemes that change such that a direct comparison between two versions no longer produces the correct result. For example, a project might be version `13` and then decide to become `1.0.0`. As `13` is translated to `13.0.0` by our versioning system by default this requires intervention. When a version scheme of a formula fails to recognise a new version as newer it must receive a [`version_scheme`](https://rubydoc.brew.sh/Formula#version_scheme%3D-class_method). An example of this can be seen [here](https://github.com/Homebrew/homebrew- core/pull/4006). ### Double-check for dependencies When you already have a lot of formulae installed, it’s easy to miss a common dependency. You can double-check which libraries a binary links to with the `otool` command (perhaps you need to use `xcrun otool`): $ otool -L /usr/local/bin/ldapvi /usr/local/bin/ldapvi: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/local/lib/libglib-2.0.0.dylib (compatibility version 4201.0.0, current version 4201.0.0) /usr/local/opt/gettext/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.2.0) /usr/local/opt/readline/lib/libreadline.6.dylib (compatibility version 6.0.0, current version 6.3.0) /usr/local/lib/libpopt.0.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0) /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP (compatibility version 1.0.0, current version 2.4.0) /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0) ### Specifying gems, Python modules, Go projects, etc. as dependencies Homebrew doesn’t package already-packaged language-specific libraries. These should be installed directly from `gem`/`cpan`/`pip` etc. If you’re installing an application then use [`resource`](https://rubydoc.brew.sh/Formula#resource-class_method)s for all language-specific dependencies: class Foo < Formula resource "pycrypto" do url "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz" sha256 "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c" end def install resource("pycrypto").stage { system "python", *Language::Python.setup_install_args(libexec/"vendor") } end end [`jrnl`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/jrnl.rb) is an example of a formula that does this well. The end result means the user doesn’t have to use `pip` or Python and can just run `jrnl`. For Python formulae, running `brew update-python-resources ` will automatically add the necessary [`resource`](https://rubydoc.brew.sh/Formula#resource-class_method) stanzas for the dependencies of your Python application to the formula. Note that `brew update-python-resources` is run automatically by `brew create` if you pass the `--python` flag. If `brew update-python-resources` is unable to determine the correct `resource` stanzas, [homebrew-pypi- poet](https://github.com/tdsmith/homebrew-pypi-poet) is a good third-party alternative that may help. ### Install the formula brew install --build-from-source --verbose --debug foo `--debug` will ask you to open an interactive shell if the build fails so you can try to figure out what went wrong. Check the top of the e.g. `./configure` output. Some configure scripts do not recognise e.g. `--disable-debug`. If you see a warning about it, remove the option from the formula. ### Add a test to the formula Add a valid test to the [`test do`](https://rubydoc.brew.sh/Formula#test- class_method) block of the formula. This will be run by `brew test foo` and the [Brew Test Bot](brew-test-bot). The [`test do`](https://rubydoc.brew.sh/Formula#test-class_method) block automatically creates and changes to a temporary directory which is deleted after run. You can access this [`Pathname`](https://rubydoc.brew.sh/Pathname) with the [`testpath`](https://rubydoc.brew.sh/Formula#testpath- instance_method) function. The environment variable `HOME` is set to [`testpath`](https://rubydoc.brew.sh/Formula#testpath-instance_method) within the [`test do`](https://rubydoc.brew.sh/Formula#test-class_method) block. 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 (despite their widespread use) `foo --version` and `foo --help` are bad tests. However, a bad test is better than no test at all. See [`cmake`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/cmake.rb) for an example of a formula with a good test. The formula writes a basic `CMakeLists.txt` file into the test directory then calls CMake to generate Makefiles. This test checks that CMake doesn’t e.g. segfault during basic operation. You can check that the output is as expected with `assert_equal` or `assert_match` on the output of the [Formula assertions](https://rubydoc.brew.sh/Homebrew/Assertions.html) such as in this example from the [envv formula](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/envv.rb): assert_equal "mylist=A:C; export mylist", shell_output("#{bin}/envv del mylist B").strip You can also check that an output file was created: assert_predicate testpath/"output.txt", :exist? Some advice for specific cases: * If the formula is a library, compile and run some simple code that links against it. It could be taken from upstream’s documentation / source examples. A good example is [`tinyxml2`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/tinyxml2.rb), which writes a small C++ source file into the test directory, compiles and links it against the tinyxml2 library and finally checks that the resulting program runs successfully. * If the formula is for a GUI program, try to find some function that runs as command-line only, like a format conversion, reading or displaying a config file, etc. * If the software cannot function without credentials or requires a virtual machine, docker instance, etc. to run, a test could be to try to connect with invalid credentials (or without credentials) and confirm that it fails as expected. This is preferred over mocking a dependency. * Homebrew comes with a number of [standard test fixtures](https://github.com/Homebrew/brew/tree/master/Library/Homebrew/test/support/fixtures), including numerous sample images, sounds, and documents in various formats. You can get the file path to a test fixture with `test_fixtures("test.svg")`. * If your test requires a test file that isn’t a standard test fixture, you can install it from a source repository during the `test` phase with a resource block, like this: resource("testdata") do url "https://example.com/input.foo" sha256 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" end test do resource("testdata").stage do assert_match "OK", shell_output("#{bin}/foo build-foo input.foo") end end ### Manuals Homebrew expects to find manual pages in `#{prefix}/share/man/...`, and not in `#{prefix}/man/...`. Some software installs to `man` instead of `share/man`, so check the output and add a `"--mandir=#{man}"` to the `./configure` line if needed. ### Caveats In case there are specific issues with the Homebrew packaging (compared to how the software is installed from other sources) a `caveats` block can be added to the formula to warn users. This can indicate non-standard install paths, an example from the `ruby` formula: ==> Caveats By default, binaries installed by gem will be placed into: /usr/local/lib/ruby/gems/bin You may want to add this to your PATH. ### A quick word on naming Name the formula like the project markets the product. So it’s `pkg-config`, not `pkgconfig`; `sdl_mixer`, not `sdl-mixer` or `sdlmixer`. The only exception is stuff like “Apache Ant”. Apache sticks “Apache” in front of everything, but we use the formula name `ant`. We only include the prefix in cases like `gnuplot` (because it’s part of the name) and `gnu-go` (because everyone calls it “GNU Go”—nobody just calls it “Go”). The word “Go” is too common and there are too many implementations of it. If you’re not sure about the name, check its homepage, Wikipedia page and [what Debian calls it](https://www.debian.org/distrib/packages). When Homebrew already has a formula called `foo` we typically do not accept requests to replace that formula with something else also named `foo`. This is to avoid both confusing and surprising users’ expectations. When two formulae share an upstream name, e.g. [AESCrypt](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/aescrypt.rb) and [AES Crypt](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/aescrypt- packetizer.rb) the newer formula must typically adapt its name to avoid conflict with the current formula. If you’re _still_ not sure, just commit. We’ll apply some arbitrary rule and make a decision 😉. When importing classes, Homebrew will require the formula and then create an instance of the class. It does this by assuming the formula name can be directly converted to the class name using a `regexp`. The rules are simple: * `foo-bar.rb` => `FooBar` * `foobar.rb` => `Foobar` Thus, if you change the name of the class, you must also rename the file. Filenames should be all lowercase, and class names should be the strict CamelCase equivalent, e.g. formulae `gnu-go` and `sdl_mixer` become classes `GnuGo` and `SdlMixer`, even if part of their name is an acronym. Add aliases by creating symlinks in an `Aliases` directory in the tap root. ### Audit the formula You can run `brew audit --strict --online` to test formulae for adherence to Homebrew house style. The `audit` command includes warnings for trailing whitespace, preferred URLs for certain source hosts, and a lot of other style issues. Fixing these warnings before committing will make the process a lot quicker for everyone. New formulae being submitted to Homebrew should run `brew audit --new-formula foo`. This command is performed by the Brew Test Bot on new submissions as part of the automated build and test process, and highlights more potential issues than the standard audit. Use `brew info` and check if the version guessed by Homebrew from the URL is correct. Add an explicit [`version`](https://rubydoc.brew.sh/Formula#version- class_method) if not. ### Commit Everything is built on Git, so contribution is easy: brew update # required in more ways than you think (initialises the brew git repository if you don't already have it) cd "$(brew --repository homebrew/core)" # Create a new git branch for your formula so your pull request is easy to # modify if any changes come up during review. git checkout -b origin/master git add Formula/foo.rb git commit The established standard for Git commit messages is: * the first line is a commit summary of _50 characters or less_ * two (2) newlines, then * explain the commit thoroughly. At Homebrew, we like to put the name of the formula up front like so: `foobar 7.3 (new formula)`. This may seem crazy short, but you’ll find that forcing yourself to summarise the commit encourages you to be atomic and concise. If you can’t summarise it in 50-80 characters, you’re probably trying to commit two commits as one. For a more thorough explanation, please read Tim Pope’s excellent blog post, [A Note About Git Commit Messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit- messages.html). The preferred commit message format for simple version updates is `foobar 7.3` and for fixes is `foobar: fix flibble matrix.`. Ensure you reference any relevant GitHub issue, e.g. `Closes #12345` in the commit message. Homebrew’s history is the first thing future contributors will look to when trying to understand the current state of formulae they’re interested in. ### Push Now you just need to push your commit to GitHub. If you haven’t forked Homebrew yet, [go to the `homebrew-core` repository and hit the Fork button](https://github.com/Homebrew/homebrew-core). If you have already forked Homebrew on GitHub, then you can manually push (just make sure you have been pulling from the `Homebrew/homebrew-core` master): git push https://github.com/myname/homebrew-core/ Now, [open a pull request](how-to-open-a-homebrew-pull-request) for your changes. * One formula per commit; one commit per formula. * Keep merge commits out of the pull request. ## Convenience tools ### Messaging Three commands are provided for displaying informational messages to the user: * `ohai` for general info * `opoo` for warning messages * `odie` for error messages and immediately exiting Use `odie` when you need to exit a formula gracefully for any reason. For example: if build.head? lib_jar = Dir["cfr-*-SNAPSHOT.jar"] doc_jar = Dir["cfr-*-SNAPSHOT-javadoc.jar"] odie "Unexpected number of artifacts!" if (lib_jar.length != 1) || (doc_jar.length != 1) end ### `bin.install "foo"` You’ll see stuff like this in some formulae. This moves the file `foo` into the formula’s `bin` directory (`/usr/local/Cellar/pkg/0.1/bin`) and makes it executable (`chmod 0555 foo`). You can also rename the file during the installation process. This can be useful for adding a prefix to binaries that would otherwise cause conflicts with another formula, or for removing a file extension. For example, to install `foo.py` into the formula’s `bin` directory (`/usr/local/Cellar/pkg/0.1/bin`) as just `foo` instead of `foo.py`: bin.install "foo.py" => "foo" ### `inreplace` [`inreplace`](https://rubydoc.brew.sh/Utils/Inreplace) is a convenience function that can edit files in-place. For example: inreplace "path", before, after `before` and `after` can be strings or regular expressions. You should use the block form if you need to make multiple replacements in a file: inreplace "path" do |s| s.gsub!(/foo/, "bar") s.gsub! "123", "456" end Make sure you modify `s`! This block ignores the returned value. [`inreplace`](https://rubydoc.brew.sh/Utils/Inreplace) should be used instead of patches when patching something that will never be accepted upstream, e.g. making the software’s build system respect Homebrew’s installation hierarchy. If it’s something that affects both Homebrew and MacPorts (i.e. macOS specific) it should be turned into an upstream submitted patch instead. If you need modify variables in a `Makefile`, rather than using [`inreplace`](https://rubydoc.brew.sh/Utils/Inreplace), pass them as arguments to `make`: system "make", "target", "VAR2=value1", "VAR2=value2", "VAR3=values can have spaces" system "make", "CC=#{ENV.cc}", "PREFIX=#{prefix}" Note that values _can_ contain unescaped spaces if you use the multiple- argument form of `system`. ## Patches While [`patch`](https://rubydoc.brew.sh/Formula#patch-class_method)es should generally be avoided, sometimes they are temporarily necessary. When [`patch`](https://rubydoc.brew.sh/Formula#patch-class_method)ing (i.e. fixing header file inclusion, fixing compiler warnings, etc.) the first thing to do is check whether or not the upstream project is aware of the issue. If not, file a bug report and/or submit your patch for inclusion. We may sometimes still accept your patch before it was submitted upstream but by getting the ball rolling on fixing the upstream issue you reduce the length of time we have to carry the patch around. _Always justify a[`patch`](https://rubydoc.brew.sh/Formula#patch-class_method) with a code comment!_ Otherwise, nobody will know when it is safe to remove the patch, or safe to leave it in when updating the formula. The comment should include a link to the relevant upstream issue(s). External [`patch`](https://rubydoc.brew.sh/Formula#patch-class_method)es can be declared using resource-style blocks: patch do url "https://example.com/example_patch.diff" sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7" 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 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7" end [`patch`](https://rubydoc.brew.sh/Formula#patch-class_method)es can be declared in [`stable`](https://rubydoc.brew.sh/Formula#stable-class_method) and [`head`](https://rubydoc.brew.sh/Formula#head-class_method) blocks. Always use a block instead of a conditional, i.e. `stable do ... end` instead of `if build.stable? then ... end`. stable do # some other things... patch do url "https://example.com/example_patch.diff" sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7" end end Embedded (**END**) patches can be declared like so: patch :DATA patch :p0, :DATA with the patch data included at the end of the file: __END__ diff --git a/foo/showfigfonts b/foo/showfigfonts index 643c60b..543379c 100644 --- a/foo/showfigfonts +++ b/foo/showfigfonts @@ -14,6 +14,7 @@ … 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, "..." In embedded patches, the string “HOMEBREW_PREFIX” is replaced with the value of the constant `HOMEBREW_PREFIX` before the patch is applied. ### Creating the diff brew install --interactive --git foo # (make some edits) git diff | pbcopy brew edit foo Now just paste into the formula after `__END__`. Instead of `git diff | pbcopy`, for some editors `git diff >> path/to/your/formula/foo.rb` might help you ensure that the patch is not touched, e.g. white space removal, indentation changes, etc. ## Advanced formula tricks If anything isn’t clear, you can usually figure it out by `grep`ping the `$(brew --repository homebrew/core)` directory. Please submit a pull request to amend this document if you think it will help! ### Handling different system configurations Often, formulae need different dependencies, resources, patches, conflicts, deprecations or `keg_only` statuses on different OSes and arches. In these cases, the components can be nested inside `on_macos`, `on_linux`, `on_arm` or `on_intel` blocks. For example, here’s how to add `gcc` as a Linux-only dependency: on_linux do depends_on "gcc" end Components can also be declared for specific macOS versions or version ranges. For example, to declare a dependency only on High Sierra, nest the `depends_on` call inside an `on_high_sierra` block. Add an `:or_older` or `:or_newer` parameter to the `on_high_sierra` method to add the dependency to all macOS versions that meet the condition. For example, to add `gettext` as a build dependency on Mojave and all later macOS versions, use: on_mojave :or_newer do depends_on "gettext" => :build end Sometimes, a dependency is needed on certain macOS versions _and_ on Linux. In these cases, a special `on_system` method can be used: on_system :linux, macos: :sierra_or_older do depends_on "gettext" => :build end To check multiple conditions, nest the corresponding blocks. For example, the following code adds a `gettext` build dependency when on ARM _and_ macOS: on_macos do on_arm do depends_on "gettext" => :build end end #### Inside `def install` and `test do` Inside `def install` and `test do`, don’t use these `on_*` methods. Instead, use `if` statements and the following conditionals: * `OS.mac?` and `OS.linux?` return `true` or `false` based on the OS * `Hardware::CPU.intel?` and `Hardware::CPU.arm?` return `true` or `false` based on the arch * `MacOS.version` returns the current macOS version. Use `==`, `<=` or `>=` to compare to symbols corresponding to macOS versions (e.g. `if MacOS.version >= :mojave`) See [`rust`](https://github.com/Homebrew/homebrew- core/blob/fe831237a7c24033a48f588a1578ba54f953f922/Formula/rust.rb#L72) for an example. ### `livecheck` blocks When `brew livecheck` is unable to identify versions for a formula, we can control its behavior using a `livecheck` block. Here is a simple example to check a page for links containing a filename like `example-1.2.tar.gz`: livecheck do url "https://www.example.com/downloads/" regex(/href=.*?example[._-]v?(\d+(?:\.\d+)+)\.t/i) end For `url`/`regex` guidelines and additional `livecheck` block examples, refer to the [`brew livecheck` documentation](brew-livecheck). For more technical information on the methods used in a `livecheck` block, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ### Unstable versions (`head`) Formulae can specify an alternate download for the upstream project’s [`head`](https://rubydoc.brew.sh/Formula#head-class_method) (`master`/`trunk`). #### `head` [`head`](https://rubydoc.brew.sh/Formula#head-class_method) URLs (activated by passing `--HEAD`) build the development cutting edge. Specifying it is easy: class Foo < Formula head "https://github.com/mxcl/lastfm-cocoa.git" end Homebrew understands `git`, `svn`, and `hg` URLs, and has a way to specify `cvs` repositories as a URL as well. You can test whether the [`head`](https://rubydoc.brew.sh/Formula#head-class_method) is being built with `build.head?`. To use a specific commit, tag, or branch from a repository, specify [`head`](https://rubydoc.brew.sh/Formula#head-class_method) with the `:tag` and `:revision`, `:revision`, or `:branch` option, like so: class Foo < Formula head "https://github.com/some/package.git", revision: "090930930295adslfknsdfsdaffnasd13" # or branch: "main" (the default is "master") # or tag: "1_0_release", revision: "090930930295adslfknsdfsdaffnasd13" end ### Compiler selection Sometimes a package fails to build when using a certain compiler. Since recent [Xcode versions](xcode) no longer include a GCC compiler we cannot simply force the use of GCC. Instead, the correct way to declare this is the [`fails_with`](https://rubydoc.brew.sh/Formula#fails_with-class_method) DSL method. A properly constructed [`fails_with`](https://rubydoc.brew.sh/Formula#fails_with-class_method) block documents the latest compiler build version known to cause compilation to fail, and the cause of the failure. For example: fails_with :clang do build 211 cause "Miscompilation resulting in segfault on queries" end `build` takes a Fixnum (an integer; you can find this number in your `brew --config` output). `cause` takes a String, and the use of heredocs is encouraged to improve readability and allow for more comprehensive documentation. [`fails_with`](https://rubydoc.brew.sh/Formula#fails_with-class_method) declarations can be used with any of `:gcc`, `:llvm`, and `:clang`. Homebrew will use this information to select a working compiler (if one is available). ### Specifying the download strategy explicitly To use one of Homebrew’s built-in download strategies, specify the `:using =>` flag on a [`url`](https://rubydoc.brew.sh/Formula#url-class_method) or [`head`](https://rubydoc.brew.sh/Formula#head-class_method). For example: class Python3 < Formula homepage "https://www.python.org/" url "https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tar.xz" sha256 "b5b3963533768d5fc325a4d7a6bd6f666726002d696f1d399ec06b043ea996b8" head "https://hg.python.org/cpython", :using => :hg Homebrew offers anonymous download strategies. `:using` value | download strategy ---|--- `:bzr` | `BazaarDownloadStrategy` `:curl` | `CurlDownloadStrategy` `:cvs` | `CVSDownloadStrategy` `:fossil` | `FossilDownloadStrategy` `:git` | `GitDownloadStrategy` `:hg` | `MercurialDownloadStrategy` `:nounzip` | `NoUnzipCurlDownloadStrategy` `:post` | `CurlPostDownloadStrategy` `:svn` | `SubversionDownloadStrategy` If you need more control over the way files are downloaded and staged, you can create a custom download strategy and specify it using the [`url`](https://rubydoc.brew.sh/Formula#url-class_method) method’s `:using` option: class MyDownloadStrategy < SomeHomebrewDownloadStrategy def fetch(timeout: nil, **options) opoo "Unhandled options in #{self.class}#fetch: #{options.keys.join(", ")}" unless options.empty? # downloads output to `temporary_path` end end class Foo < Formula url "something", :using => MyDownloadStrategy end ### Just moving some files When your code in the install function is run, the current working directory is set to the extracted tarball. So it is easy to just move some files: prefix.install "file1", "file2" Or everything: prefix.install Dir["output/*"] Generally we’d rather you were specific about what files or directories need to be installed rather than installing everything. #### Variables for directory locations Name | Default | Example ---|---|--- **`HOMEBREW_PREFIX`** | `/usr/local` | **`prefix`** | `#{HOMEBREW_PREFIX}/Cellar/#{name}/#{version}` | `/usr/local/Cellar/foo/0.1` **`opt_prefix`** | `#{HOMEBREW_PREFIX}/opt/#{name}` | `/usr/local/opt/foo` **`bin`** | `#{prefix}/bin` | `/usr/local/Cellar/foo/0.1/bin` **`doc`** | `#{prefix}/share/doc/#{name}` | `/usr/local/Cellar/foo/0.1/share/doc/foo` **`include`** | `#{prefix}/include` | `/usr/local/Cellar/foo/0.1/include` **`info`** | `#{prefix}/share/info` | `/usr/local/Cellar/foo/0.1/share/info` **`lib`** | `#{prefix}/lib` | `/usr/local/Cellar/foo/0.1/lib` **`libexec`** | `#{prefix}/libexec` | `/usr/local/Cellar/foo/0.1/libexec` **`man`** | `#{prefix}/share/man` | `/usr/local/Cellar/foo/0.1/share/man` **`man[1-8]`** | `#{prefix}/share/man/man[1-8]` | `/usr/local/Cellar/foo/0.1/share/man/man[1-8]` **`sbin`** | `#{prefix}/sbin` | `/usr/local/Cellar/foo/0.1/sbin` **`share`** | `#{prefix}/share` | `/usr/local/Cellar/foo/0.1/share` **`pkgshare`** | `#{prefix}/share/#{name}` | `/usr/local/Cellar/foo/0.1/share/foo` **`elisp`** | `#{prefix}/share/emacs/site-lisp/#{name}` | `/usr/local/Cellar/foo/0.1/share/emacs/site-lisp/foo` **`frameworks`** | `#{prefix}/Frameworks` | `/usr/local/Cellar/foo/0.1/Frameworks` **`kext_prefix`** | `#{prefix}/Library/Extensions` | `/usr/local/Cellar/foo/0.1/Library/Extensions` **`zsh_function`** | `#{prefix}/share/zsh/site-functions` | `/usr/local/Cellar/foo/0.1/share/zsh/site-functions` **`fish_function`** | `#{prefix}/share/fish/vendor_functions` | `/usr/local/Cellar/foo/0.1/share/fish/vendor_functions` **`bash_completion`** | `#{prefix}/etc/bash_completion.d` | `/usr/local/Cellar/foo/0.1/etc/bash_completion.d` **`zsh_completion`** | `#{prefix}/share/zsh/site-functions` | `/usr/local/Cellar/foo/0.1/share/zsh/site-functions` **`fish_completion`** | `#{prefix}/share/fish/vendor_completions.d` | `/usr/local/Cellar/foo/0.1/share/fish/vendor_completions.d` **`etc`** | `#{HOMEBREW_PREFIX}/etc` | `/usr/local/etc` **`pkgetc`** | `#{HOMEBREW_PREFIX}/etc/#{name}` | `/usr/local/etc/foo` **`var`** | `#{HOMEBREW_PREFIX}/var` | `/usr/local/var` **`buildpath`** | A temporary directory somewhere on your system | `/private/tmp/[formula-name]-0q2b/[formula-name]` These can be used, for instance, in code such as bin.install Dir["output/*"] to move binaries into their correct location into the Cellar, and man.mkpath to create the directory structure for the manual page location. To install man pages into specific locations, use `man1.install "foo.1", "bar.1"`, `man2.install "foo.2"`, etc. Note that in the context of Homebrew, [`libexec`](https://rubydoc.brew.sh/Formula#libexec-instance_method) is reserved for private use by the formula and therefore is not symlinked into `HOMEBREW_PREFIX`. ### Adding optional steps **Note:** [`option`](https://rubydoc.brew.sh/Formula#option-class_method)s are not allowed in Homebrew/homebrew-core as they are not tested by CI. If you want to add an [`option`](https://rubydoc.brew.sh/Formula#option- class_method): class Yourformula < Formula ... option "with-ham", "Description of the option" option "without-spam", "Another description" depends_on "foo" => :optional # will automatically add a with-foo option ... And then to define the effects the [`option`](https://rubydoc.brew.sh/Formula#option-class_method)s have: if build.with? "ham" # note, no "with" in the option name (it is added by the build.with? method) end if build.without? "ham" # works as you'd expect. True if `--without-ham` was given. end [`option`](https://rubydoc.brew.sh/Formula#option-class_method) names should be prefixed with the words `with` or `without`. For example, an option to run a test suite should be named `--with-test` or `--with-check` rather than `--test`, and an option to enable a shared library `--with-shared` rather than `--shared` or `--enable-shared`. [`option`](https://rubydoc.brew.sh/Formula#option-class_method)s that aren’t `build.with? ` or `build.without?` should be deprecated with [`deprecated_option`](https://rubydoc.brew.sh/Formula#deprecated_option- class_method). See [`wget`](https://github.com/Homebrew/homebrew- core/blob/3f762b63c6fbbd49191ffdf58574d7e18937d93f/Formula/wget.rb#L27-L31) for an example. ### File level operations You can use the file utilities provided by Ruby’s [`FileUtils`](https://www.ruby- doc.org/stdlib/libdoc/fileutils/rdoc/index.html). These are included in the [`Formula`](https://rubydoc.brew.sh/Formula) class, so you do not need the `FileUtils.` prefix to use them. When creating symlinks, take special care to ensure they are _relative_ symlinks. This makes it easier to create a relocatable bottle. For example, to create a symlink in `bin` to an executable in `libexec`, use bin.install_symlink libexec/"name" instead of: ln_s libexec/"name", bin The symlinks created by [`install_symlink`](https://rubydoc.brew.sh/Pathname#install_symlink- instance_method) are guaranteed to be relative. `ln_s` will only produce a relative symlink when given a relative path. ### Rewriting a script shebang Some formulae install executable scripts written in an interpreted language such as Python or Perl. Homebrew provides a `rewrite_shebang` method to rewrite the shebang of a script. This replaces a script’s original interpreter path with the one the formula depends on. This guarantees that the correct interpreter is used at execution time. This isn’t required if the build system already handles it (e.g. often with `pip` or Perl `ExtUtils::MakeMaker`). For example, the [`icdiff` formula](https://github.com/Homebrew/homebrew- core/blob/7beae5ab57c65249403699b2b0700fbccf14e6cb/Formula/icdiff.rb#L16) uses such utility. Note that it is necessary to include the utility in the formula, for example with Python one must use `include Language::Python::Shebang`. ### Handling files that should persist over formula upgrades For example, Ruby 1.9’s gems should be installed to `var/lib/ruby/` so that gems don’t need to be reinstalled when upgrading Ruby. You can usually do this with symlink trickery, or (ideally) a configure option. Another example would be configuration files that should not be overwritten on package upgrades. If after installation you find that to-be-persisted configuration files are not copied but instead _symlinked_ into `/usr/local/etc/` from the Cellar, this can often be rectified by passing an appropriate argument to the package’s configure script. That argument will vary depending on a given package’s configure script and/or Makefile, but one example might be: `--sysconfdir=#{etc}` ### Service files There are two ways to add plists and systemd services to a formula, so that [`brew services`](https://github.com/Homebrew/homebrew-services) can pick it up: 1. If the formula already provides a file the formula can install it into the prefix like so. prefix.install_symlink "file.plist" => "#{plist_name}.plist" prefix.install_symlink "file.service" => "#{service_name}.service" 1. If the formula does not provide a service you can generate one using the following stanza. service do run bin/"script" end #### Service block methods There are many more options you can set within such a block, and in this table you will find them all. The only required field in a `service` block is the `run` field to indicate what to run. Method | Default | macOS | Linux | Description ---|---|---|---|--- `run` | - | yes | yes | Command to execute, an array with arguments or a path `run_type` | `:immediate` | yes | yes | The type of service, `:immediate`, `:interval` or `:cron` `keep_alive` | `false` | yes | yes | If the service needs to keep the process running after exit `interval` | - | yes | yes | Controls the start interval, required for the `:interval` type `cron` | - | yes | yes | Controls the trigger times, required for the `:cron` type `launch_only_once` | false | yes | yes | If the command should only run once `environment_variables` | - | yes | yes | A hash of variables to set `working_dir` | - | yes | yes | The directory to operate from `root_dir` | - | yes | yes | The directory to use as a chroot for the process `input_path` | - | yes | yes | Path to use as input for the process `log_path` | - | yes | yes | Path to write stdout to `error_log_path` | - | yes | yes | Path to write stderr to `restart_delay` | - | yes | yes | The delay before restarting a process `process_type` | - | yes | no-op | The type of process to manage, `:background`, `:standard`, `:interactive` or `:adaptive` `macos_legacy_timers` | - | yes | no-op | Timers created by launchd jobs are coalesced unless this is set `sockets` | - | yes | no-op | A socket that is created as an accesspoint to the service For services that start and keep running alive you can use the default `run_type :` like so: service do run [opt_bin/"beanstalkd", "test"] keep_alive true run_type :immediate # This should be omitted since it's the default end If a service needs to run on an interval, use `run_type :interval` and specify an interval: service do run [opt_bin/"beanstalkd", "test"] run_type :interval interval 500 end If a service needs to run at certain times, use `run_type :cron` and specify a time with the crontab syntax: service do run [opt_bin/"beanstalkd", "test"] run_type :cron cron "5 * * * *" end For environment variables you can specify a hash. For the path there is the helper method `std_service_path_env`. This method will set the path to `#{HOMEBREW_PREFIX}/bin:#{HOMEBREW_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin` so the service can find other `brew` commands. service do run opt_bin/"beanstalkd" environment_variables PATH: std_service_path_env end #### KeepAlive options The standard options, keep alive regardless of any status or circomstances service do run [opt_bin/"beanstalkd", "test"] keep_alive true # or false end Same as above in hash form service do run [opt_bin/"beanstalkd", "test"] keep_alive { always: true } end Keep alive until the job exits with a non-zero return code service do run [opt_bin/"beanstalkd", "test"] keep_alive { succesful_exit: true } end Keep alive only if the job crashed service do run [opt_bin/"beanstalkd", "test"] keep_alive { crashed: true } end Keep alive as long as a file exists service do run [opt_bin/"beanstalkd", "test"] keep_alive { path: "/some/path" } end #### Socket format The sockets method accepts a formatted socket definition as `://:`. * `type`: `udp` or `tcp` * `host`: The host to run the socket on. For example `0.0.0.0` * `port`: The port the socket should listen on. Please note that sockets will be accessible on IPv4 and IPv6 addresses by default. ### Using environment variables Homebrew has multiple levels of environment variable filtering which affects variables available to formulae. Firstly, the overall environment in which Homebrew runs is filtered to avoid environment contamination breaking from-source builds (). In particular, this process filters all but the given whitelisted variables, but allows environment variables prefixed with `HOMEBREW_`. The specific implementation can be seen in [`bin/brew`](https://github.com/Homebrew/brew/blob/HEAD/bin/brew). The second level of filtering removes sensitive environment variables (such as credentials like keys, passwords or tokens) to avoid malicious subprocesses obtaining them (). This has the effect of preventing any such variables from reaching a formula’s Ruby code as they are filtered before it is called. The specific implementation can be seen in the [`ENV.clear_sensitive_environment!` method](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/extend/ENV.rb). You can set environment variables in a formula’s `install` method using `ENV["VARIABLE_NAME"] = "VALUE"`. An example can be seen in [the `gh` formula](https://github.com/Homebrew/homebrew- core/blob/fd9ad29f8e3ca9476f838ebb13794ddb7dafba00/Formula/gh.rb#L22). Environment variables can also be set temporarily using the `with_env` method; any variables defined in the call to that method will be restored to their original values at the end of the block. An example can be seen in [the `csound` formula](https://github.com/Homebrew/homebrew- core/blob/c3feaff8cdb578331385676620c865796cfc3388/Formula/csound.rb#L155-L157). In summary, environment variables used by a formula need to conform to these filtering rules in order to be available. ### Deprecating and disabling a formula See our [Deprecating, Disabling, and Removing Formulae](deprecating-disabling- and-removing-formulae) documentation for more information about how and when to deprecate or disable a formula. ## Updating formulae Eventually a new version of the software will be released. In this case you should update the [`url`](https://rubydoc.brew.sh/Formula#url-class_method) and [`sha256`](https://rubydoc.brew.sh/Formula#sha256%3D-class_method). You can use: brew bump-formula-pr foo If a [`revision`](https://rubydoc.brew.sh/Formula#revision%3D-class_method) line exists outside any `bottle do` block it should be removed. Leave the `bottle do ... end` block as-is; our CI system will update it when we pull your change. Check if the formula you are updating is a dependency for any other formulae by running `brew uses `. If it is a dependency, run `brew reinstall` for all the dependencies after it is installed and verify they work correctly. ## Style guide Homebrew wants to maintain a consistent Ruby style across all formulae mostly based on [Ruby Style Guide](https://github.com/rubocop-hq/ruby-style- guide#the-ruby-style-guide). Other formulae may not have been updated to match this guide yet but all new ones should. Also: * The order of methods in a formula should be consistent with other formulae (e.g.: `def install` goes before `def post_install`). * An empty line is required before the `__END__` line. ## Troubleshooting for people writing new formulae ### Version detection fails Homebrew tries to automatically determine the [`version`](https://rubydoc.brew.sh/Formula#version-class_method) from the [`url`](https://rubydoc.brew.sh/Formula#url-class_method) to avoid duplication. If the tarball has an unusual name you may need to manually assign the [`version`](https://rubydoc.brew.sh/Formula#version-class_method). ### Bad makefiles Not all projects have makefiles that will run in parallel so try to deparallelize by adding these lines to the `install` method: ENV.deparallelize system "make" # separate make and make install steps system "make", "install" If that fixes it, please open an [issue](https://github.com/Homebrew/homebrew- core/issues) so that we can fix it for everyone. ### Still won’t work? Check out what MacPorts and Fink do: brew search --macports foo brew search --fink foo ## Superenv notes `superenv` is our “super environment” that isolates builds by removing `/usr/local/bin` and all user `PATH`s that are not essential for the build. It does this because user `PATH`s are often full of stuff that breaks builds. `superenv` also removes bad flags from the commands passed to `clang`/`gcc` and injects others (for example all [`keg_only`](https://rubydoc.brew.sh/Formula#keg_only-class_method) dependencies are added to the `-I` and `-L` flags). ## Fortran Some software requires a Fortran compiler. This can be declared by adding `depends_on "gcc"` to a formula. ## MPI Formula requiring MPI should use [OpenMPI](https://www.open-mpi.org/) by adding `depends_on "open-mpi"` to the formula, rather than [MPICH](https://www.mpich.org/). These packages have conflicts and provide the same standardised interfaces. Choosing a default implementation and requiring it to be adopted allows software to link against multiple libraries that rely on MPI without creating un-anticipated incompatibilities due to differing MPI runtimes. ## Linear algebra libraries By default packages that require BLAS/LAPACK linear algebra interfaces should link to [OpenBLAS](https://www.openblas.net/) using `depends_on "openblas"` and passing `-DBLA_VENDOR=OpenBLAS` to CMake (applies to CMake based formula only) rather than Apple’s Accelerate framework, or the default reference lapack implementation. Apple’s implementation of BLAS/LAPACK is outdated and may introduce hard-to-debug problems. The reference `lapack` formula is fine, although it is not actively maintained or tuned. For this reason, formulae needing BLAS/LAPACK should link with OpenBLAS. ## How to start over (reset to upstream `master`) Have you created a real mess in Git which stops you from creating a commit you want to submit to us? You might want to consider starting again from scratch. Your changes can be reset to the Homebrew `master` branch by running: git checkout -f master git reset --hard origin/master # Gems, Eggs and Perl Modules On a fresh macOS installation there are three empty directories for add-ons available to all users: * `/Library/Ruby` * `/Library/Python` * `/Library/Perl` You need sudo to install to these like so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`. ## Python packages (eggs) without sudo using system Python An option to avoid sudo is to use an access control list. For example: chmod +a 'user: allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/3.y/site-packages will let you add packages to Python 3.y as yourself, which is probably safer than changing the group ownership of the directory. ### So why was I using sudo? Habit maybe? One reason is executables go in `/usr/local/bin`. Usually this isn’t a writable location. But if you installed Homebrew as we recommend on macOS Intel, `/usr/local` will be writable without sudo. So now you are good to install the development tools you need without risking the use of sudo. ### An alternative package path _This is only recommended if you**don’t** use a brewed Python._ On macOS, any Python version X.Y [also searches in `~/Library/Python/X.Y/lib/python/site-packages` for modules](https://docs.python.org/2/install/index.html#alternate-installation- the-user-scheme). That path might not yet exist, but you can create it: mkdir -p ~/Library/Python/2.7/lib/python/site-packages To teach `easy_install` and `pip` to install there, either use the `--user` switch or create a `~/.pydistutils.cfg` file with the following content: [install] install_lib = ~/Library/Python/$py_version_short/lib/python/site-packages ### Using virtualenv (with system Python) [Virtualenv](https://virtualenv.pypa.io/) ships `pip` and creates isolated Python environments with separate `site-packages`, which therefore don’t need sudo. ## Rubygems without sudo _This is only recommended if you**don’t** use rbenv or RVM._ Brewed Ruby installs executables to `$(brew --prefix)/opt/ruby/bin` without sudo. You should add this to your path. See the caveats in the `ruby` formula for up-to-date information. ### With system Ruby To make Ruby install to `/usr/local`, we need to add `gem: -n/usr/local/bin` to your `~/.gemrc`. It’s YAML, so do it manually or use this: echo "gem: -n/usr/local/bin" >> ~/.gemrc **However, all versions of RubyGems before 1.3.6 are buggy** and ignore the above setting. Sadly a fresh install of Snow Leopard comes with 1.3.5. Currently the only known way to get around this is to upgrade rubygems as root: sudo gem update --system ### An alternative gem path Just install everything into the Homebrew prefix like this: echo "export GEM_HOME=\"$(brew --prefix)\"" >> ~/.bashrc ### It doesn’t work! I get some “permissions” error when I try to install stuff! _Note that you may not want to do this, since Apple has decided it is not a good default._ If you ever did a `sudo gem`, etc. before then a lot of files will have been created owned by root. Fix with: sudo chown -R $(whoami) /Library/Ruby/* /Library/Perl/* /Library/Python/* ## Perl CPAN modules without sudo The Perl module `local::lib` works similarly to rbenv/RVM (although for modules only, not Perl installations). A simple solution that only pollutes your `/Library/Perl` a little is to install [`local::lib`](https://metacpan.org/pod/local::lib) with sudo: sudo cpan local::lib Note that this will install some other dependencies like `Module::Install`. Then put the appropriate incantation in your shell’s startup, e.g. for `.profile` you’d insert the below; for others see the [`local::lib`](https://metacpan.org/pod/local::lib) docs. eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)" Now (after you restart your shell) `cpan` or `perl -MCPAN -eshell` etc. will install modules and binaries in `~/perl5` and the relevant subdirectories will be in your `PATH` and `PERL5LIB`. ### Avoiding sudo altogether for Perl If you don’t even want (or can’t) use sudo for bootstrapping `local::lib`, just manually install `local::lib` in `~/perl5` and add the relevant path to `PERL5LIB` before the `.bashrc` eval incantation. Another alternative is to use `perlbrew` to install a separate copy of Perl in your home directory, or wherever you like: curl -L https://install.perlbrew.pl | bash perlbrew install perl-5.16.2 echo ".~/perl5/perlbrew/etc/bashrc" >> ~/.bashrc # Python This page describes how Python is handled in Homebrew for users. See [Python for Formula Authors](python-for-formula-authors) for advice on writing formulae to install packages written in Python. Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference- between-cpython-and-python) and defaults to the macOS system Python. Homebrew provides formulae to brew Python 3.y. A `python@2` formula was provided until the end of 2019, at which point it was removed due to the Python 2 deprecation. **Important:** If you choose to use a Python which isn’t either of these two (system Python or brewed Python), the Homebrew team cannot support any breakage that may occur. ## Python 3.y Homebrew provides formulae for maintained releases of Python 3.y (`python@3.y`). **Important:** Python may be upgraded to a newer version at any time. Consider using a version manager such as `pyenv` if you require stability of minor or patch versions for virtual environments. The executables are organised as follows: * `python3` points to Homebrew’s Python 3.y (if installed) * `pip3` points to Homebrew’s Python 3.y’s pip (if installed) Unversioned symlinks for `python`, `python-config`, `pip` etc. are installed here: $(brew --prefix)/opt/python/libexec/bin ## Setuptools, Pip, etc. The Python formulae install [pip](https://pip.pypa.io/) (as `pip3`) and [Setuptools](https://pypi.org/project/setuptools/). Setuptools can be updated via pip3, without having to re-brew Python: python3 -m pip install --upgrade setuptools Similarly, pip3 can be used to upgrade itself via: python3 -m pip install --upgrade pip ## `site-packages` and the `PYTHONPATH` The `site-packages` is a directory that contains Python modules, including bindings installed by other formulae. Homebrew creates it here: $(brew --prefix)/lib/pythonX.Y/site-packages So, for Python 3.y.z, you’ll find it at `/usr/local/lib/python3.y/site- packages`. Python 3.y also searches for modules in: * `/Library/Python/3.y/site-packages` * `~/Library/Python/3.y/lib/python/site-packages` Homebrew’s `site-packages` directory is first created (1) once any Homebrew formulae with Python bindings are installed, or (2) upon `brew install python`. ### Why here? The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don’t spam your system. ## Homebrew-provided Python bindings Some formulae provide Python bindings. **Warning!** Python may crash (see [Common Issues](common-issues)) when you `import ` from a brewed Python if you ran `brew install ` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pyqt`, `pygobject3`, `opencv`, `vtk` and `boost- python`). ## Policy for non-brewed Python bindings These should be installed via `pip install `. To discover, you can use `pip search` or . **Note:** macOS’s system Python does not provide `pip`. Follow the [pip documentation](https://pip.pypa.io/en/stable/installation/) to install it for your system Python if you would like it. ## Brewed Python modules For brewed Python, modules installed with `pip3` or `python3 setup.py install` will be installed to the `$(brew --prefix)/lib/pythonX.Y/site-packages` directory (explained above). Executable Python scripts will be in `$(brew --prefix)/bin`. Since the system Python may not know which compiler flags to set when building bindings for software installed by Homebrew, you may need to run: CFLAGS="-I$(brew --prefix)/include" LDFLAGS="-L$(brew --prefix)/lib" pip install ## Virtualenv **Warning!** When you `brew install` formulae that provide Python bindings, you should **not be in an active virtual environment**. Activate the virtualenv _after_ you’ve brewed, or brew in a fresh terminal window. This will ensure Python modules are installed into Homebrew’s `site- packages` and _not_ into that of the virtual environment. Virtualenv has a `--system-site-packages` switch to allow “global” (i.e. Homebrew’s) `site-packages` to be accessible from within the virtualenv. ## Why is Homebrew’s Python being installed as a dependency? Formulae that declare an unconditional dependency on the `python` formula are bottled against Homebrew’s Python 3.y and require it to be installed. # Homebrew Governance Responsibilities ## Project Leadership Committee ### PLC Sole Responsibilities * organising the AGM * voting on maintainer hardware grants (before they are purchased) * voting on maintainer hackathon/conference/AGM travel expenses (before they are booked) * responding to and handling Code of Conduct complaints * removing inactive members (that are not maintainers) that did not vote in the AGM ### PLC Shared Responsibilities * approving Open Collective expenses that are expected or have already been agreed upon by the PLC (e.g. Homebrew cloud usage on a personal credit card) (only one approval needed) * blocking abusive GitHub users * performing GitHub admin operations on the Homebrew GitHub organisation * performing Slack admin operations on the Homebrew Slack ### PLC Dated Yearly Tasks * January: check membership, announce AGM votes * Ask for nominations for the for the PLC and project leader, and ask who is interested in serving on the TSC * Create ballots for the elections on https://www.opavote.com * Ask the project leader and representatives of the PLC and TSC to prepare reports for the AGM * Ask for members interested in presenting lightning talks at the AGM * February: organise the annual general meeting (AGM) * Create a dedicated Slack channel * Book a group dinner (which Homebrew pays for) and check for any dietary requirements * Ask someone to bring a conference/table microphone for people to be able to remotely participate in AGM * February after the AGM: * Add the minutes of the AGM to https://github.com/Homebrew/homebrew-governance * Create [issue in homebrew-governance](https://github.com/homebrew/homebrew-governance/issues) to ask members who did not vote in the election whether they wish to remain or step down as members * Members that are not maintainers should be a least one of: * An current or previously active maintainer, PLC/TSC member or Project Leader * A long-standing member of the Homebrew community (e.g. been submitting good bug reports for over two years) * October: arrange in-person AGM * Offer to pay for Homebrew maintainers who are at least one of: * active Homebrew maintainers (i.e. not just contributors) * new Homebrew maintainers (i.e. this would be their first AGM) * current members of or running for election for PLC/TSC/Project Leader * Authorise people to book travel ## Project Leader ### PL Sole Responsibilities * manage all day-to-day technical decisions * resolve disputes related to the operation of Homebrew between maintainers, members, other contributors, and users * [product management](https://en.wikipedia.org/wiki/Product_management) for the various Homebrew products * in February, before the AGM: checking for activity of non-PLC/TSC maintainers and asking them to step down if they have not been active enough in the past 12 months ### PL Shared Responsibilities * approving new Homebrew maintainers (only one approval needed) * approving Open Collective expenses that are expected or have already been agreed upon by the PLC (e.g. Homebrew cloud usage on a personal credit card) (only one approval needed) * blocking abusive GitHub users * performing GitHub admin operations on the Homebrew GitHub organisation * performing Slack admin operations on the Homebrew Slack ## Technical Steering Committee ### TSC Sole Responsibilities * decide on technical disputes between Homebrew maintainers and the Project Leader ### TSC Shared Responsibilities * approving new Homebrew maintainers (only one approval needed) * blocking abusive GitHub users * performing GitHub admin operations on the Homebrew GitHub organisation # Homebrew on Linux The Homebrew package manager may be used on Linux and [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about). Homebrew was formerly referred to as Linuxbrew when running on Linux or WSL. It can be installed in your home directory, in which case it does not use _sudo_. Homebrew does not use any libraries provided by your host system, except _glibc_ and _gcc_ if they are new enough. Homebrew can install its own current versions of _glibc_ and _gcc_ for older distributions of Linux. Features, installation instructions and requirements are described below. Terminology (e.g. the difference between a Cellar, Tap, Cask and so forth) is [explained in the documentation](formula-cookbook#homebrew-terminology). ## Features * Can install software to your home directory and so does not require _sudo_ * Install software not packaged by your host distribution * Install up-to-date versions of software when your host distribution is old * Use the same package manager to manage your macOS, Linux, and Windows systems ## Install Instructions for a supported install of Homebrew on Linux are on the [homepage](https://brew.sh). The installation script installs Homebrew to `/home/linuxbrew/.linuxbrew` using _sudo_ if possible and within your home directory at `~/.linuxbrew` otherwise. Homebrew does not use _sudo_ after installation. Using `/home/linuxbrew/.linuxbrew` allows the use of more binary packages (bottles) than installing in your personal home directory. The prefix `/home/linuxbrew/.linuxbrew` was chosen so that users without admin access can ask an admin to create a `linuxbrew` role account and still benefit from precompiled binaries. If you do not yourself have admin privileges, consider asking your admin staff to create a `linuxbrew` role account for you with home directory set to `/home/linuxbrew`. Follow the _Next steps_ instructions to add Homebrew to your `PATH` and to your bash shell profile script, either `~/.profile` on Debian/Ubuntu or `~/.bash_profile` on CentOS/Fedora/Red Hat. test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)" test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" test -r ~/.bash_profile && echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.bash_profile echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.profile You’re done! Try installing a package: brew install hello If you’re using an older distribution of Linux, installing your first package will also install a recent version of _glibc_ and _gcc_. Use `brew doctor` to troubleshoot common issues. ## Requirements * **GCC** 4.7.0 or newer * **Linux** 2.6.32 or newer * **Glibc** 2.13 or newer * **64-bit x86_64** CPU To install build tools, paste at a terminal prompt: * **Debian or Ubuntu** sudo apt-get install build-essential procps curl file git * **Fedora, CentOS, or Red Hat** sudo yum groupinstall 'Development Tools' sudo yum install procps-ng curl file git sudo yum install libxcrypt-compat # needed by Fedora 30 and up ### ARM Homebrew can run on 32-bit ARM (Raspberry Pi and others) and 64-bit ARM (AArch64), but no binary packages (bottles) are available. Support for ARM is on a best-effort basis. Pull requests are welcome to improve the experience on ARM platforms. You may need to install your own Ruby using your system package manager, a PPA, or `rbenv/ruby-build` as we no longer distribute a Homebrew Portable Ruby for ARM. ### 32-bit x86 Homebrew does not currently support 32-bit x86 platforms. It would be possible for Homebrew to work on 32-bit x86 platforms with some effort. An interested and dedicated person could maintain a fork of Homebrew to develop support for 32-bit x86. ## Homebrew on Linux Community * [@HomebrewOnLinux on Twitter](https://twitter.com/HomebrewOnLinux) * [Homebrew/discussions (forum)](https://github.com/homebrew/discussions/discussions) # How to Build Software Outside Homebrew with Homebrew `keg_only` Dependencies ## What does “keg-only” mean? The [FAQ](faq#what-does-keg-only-mean) briefly explains this. As an example: _OpenSSL isn’t symlinked into my`PATH` and non-Homebrew builds can’t find it!_ This is because Homebrew isolates it within its individual prefix, rather than symlinking to the publicly available location. ## Advice on potential workarounds A number of people in this situation are either forcefully linking keg-only tools with `brew link --force` or moving default system utilities out of the `PATH` and replacing them with manually created symlinks to the Homebrew- provided tool. _Please_ do not remove macOS native tools and forcefully replace them with symlinks back to the Homebrew-provided tool. Doing so can and likely will cause significant breakage when attempting to build software. `brew link --force` creates a warning in `brew doctor` to let both you and maintainers know that a link exists that could be causing issues. If you’ve linked something and there’s no problems at all? Feel free to ignore the `brew doctor` error. ## How do I use those tools outside of Homebrew? Useful, reliable alternatives exist should you wish to use keg-only tools outside of Homebrew. ### Build flags You can set flags to give configure scripts or Makefiles a nudge in the right direction. An example of flag setting: ./configure --prefix=/Users/Dave/Downloads CFLAGS="-I$(brew --prefix)/opt/openssl/include" LDFLAGS="-L$(brew --prefix)/opt/openssl/lib" An example using `pip`: CFLAGS="-I$(brew --prefix)/opt/icu4c/include" LDFLAGS="-L$(brew --prefix)/opt/icu4c/lib" pip install pyicu ### `PATH` modification You can temporarily prepend your `PATH` with the tool’s `bin` directory, such as: export PATH="$(brew --prefix)/opt/openssl/bin:${PATH}" This will prepend the directory to your `PATH`, ensuring any build script that searches the `PATH` will find it first. Changing your `PATH` using this command ensures the change only exists for the duration of the shell session. Once the current session ends, the `PATH` reverts to its prior state. ### `pkg-config` detection If the tool you are attempting to build is [pkg- config](https://en.wikipedia.org/wiki/Pkg-config) aware, you can amend your `PKG_CONFIG_PATH` to find a keg-only utility’s `.pc` files, if it has any. Not all formulae ship with these files. An example of this is: export PKG_CONFIG_PATH="$(brew --prefix)/opt/openssl/lib/pkgconfig" If you’re curious about the `PKG_CONFIG_PATH` variable, `man pkg-config` goes into more detail. You can get `pkg-config` to print the default search path with: pkg-config --variable pc_path pkg-config # How to Create and Maintain a Tap [Taps](taps) are external sources of Homebrew formulae, casks and/or external commands. They can be created by anyone to provide their own formulae, casks and/or external commands to any Homebrew user. ## Creating a tap A tap is usually a Git repository available online, but you can use anything as long as it’s a protocol that Git understands, or even just a directory with files in it. If hosted on GitHub, we recommend that the repository’s name start with `homebrew-` so the short `brew tap` command can be used. See the [manpage](manpage) for more information on repository naming. The `brew tap-new` command can be used to create a new tap along with some template files. Tap formulae follow the same format as the core’s ones, and can be added under either the `Formula` subdirectory, the `HomebrewFormula` subdirectory or the repository’s root. The first available directory is used, other locations will be ignored. We recommend use of subdirectories because it makes the repository organisation easier to grasp, and top-level files are not mixed with formulae. See [homebrew/core](https://github.com/Homebrew/homebrew-core) for an example of a tap with a `Formula` subdirectory. ## Naming your formulae to avoid clashes If your formulae have the same name as Homebrew/homebrew-core formulae they cannot be installed side-by-side. If you wish to create a different version of a formula that’s in Homebrew/homebrew-core (e.g. with `option`s) consider giving it a different name e.g. `nginx-full` for more fully-featured `nginx` formula. This will allow both `nginx` and `nginx-full` to be installed at the same time (assuming one is `keg_only` or the linked files do not clash). ### Installing If it’s on GitHub, users can install any of your formulae with `brew install user/repo/formula`. Homebrew will automatically add your `github.com/user/homebrew-repo` tap before installing the formula. `user/repo/formula` points to the `github.com/user/homebrew- repo/**/formula.rb` file here. If they want to get your tap without installing any formula at the same time, users can add it with the [`brew tap` command](taps). If it’s on GitHub, they can use `brew tap user/repo`, where `user` is your GitHub username and `homebrew-repo` is your repository. If it’s hosted outside of GitHub, they have to use `brew tap user/repo `, where `user` and `repo` will be used to refer to your tap and `` is your Git clone URL. Users can then install your formulae either with `brew install foo` if there’s no core formula with the same name, or with `brew install user/repo/foo` to avoid conflicts. ## Maintaining a tap A tap is just a Git repository so you don’t have to do anything specific when making modifications, apart from committing and pushing your changes. ### Updating Once your tap is installed, Homebrew will update it each time a user runs `brew update`. Outdated formulae will be upgraded when a user runs `brew upgrade`, like core formulae. ## Casks Casks can also be installed from a tap. Casks can be included in taps with formulae, or in a tap with just casks. Place any cask files you wish to make available in a `Casks` directory at the top level of your tap. See [homebrew/cask](https://github.com/Homebrew/homebrew-cask) for an example of a tap with a `Casks` subdirectory. ### Naming Unlike formulae, casks must have globally unique names to avoid clashes. This can be achieved by e.g. prepending the cask name with your github username: `username-formula-name`. ## External commands You can provide your tap users with custom `brew` commands by adding them in a `cmd` subdirectory. [Read more on external commands](external-commands). See [homebrew/aliases](https://github.com/Homebrew/homebrew-aliases) for an example of a tap with external commands. ## Official Vendor Taps Some upstream software providers like to package their software in their own Homebrew tap. When their software is [eligible for Homebrew/homebrew- core](acceptable-formulae) we prefer to maintain software there for ease of updates, improved discoverability and use of tools such as [formulae.brew.sh](https://formulae.brew.sh). We are not willing to remove software packaged in Homebrew/homebrew-core in favour of an upstream tap. We are not willing to instruct users in our formulae to use your formulae instead. If upstream projects have issues with how Homebrew packages your software: please file issues (or, ideally, pull requests) to address these problems. There’s an increasing desire in commercial open source about “maintaining control” e.g. defining exactly what binaries are shipping to users. Not supporting users (or even software distributions) to build-from-source is antithetical to the values of open source. If you think Homebrew’s perspective is annoying on this: try and see how Debian responds to requests to ship your binaries. # How To Open a Homebrew Pull Request The following commands are used by Homebrew contributors to set up a fork of Homebrew’s Git repository on GitHub, create a new branch and create a GitHub pull request (“PR”) of the changes in that branch. Depending on the change you want to make, you need to send the pull request to the appropriate one of Homebrew’s main repositories. If you want to submit a change to Homebrew core code (the `brew` implementation), you should open the pull request on [Homebrew/brew](https://github.com/Homebrew/brew). If you want to submit a change for a formula, you should open the pull request on the [homebrew/core](https://github.com/Homebrew/homebrew-core) tap, for casks you should open the pull request on the [homebrew/cask](https://github.com/Homebrew/homebrew-cask) tap or another [official tap](https://github.com/Homebrew), based on the formula type. ## Submit a new version of an existing formula 1. Use `brew bump-formula-pr` to do everything (i.e. forking, committing, pushing) with a single command. Run `brew bump-formula-pr --help` to learn more. ## Submit a new version of an existing cask 1. Use `brew bump-cask-pr` to do everything (i.e. forking, committing, pushing) with a single command. Run `brew bump-cask-pr --help` to learn more. ## Set up your own fork of the Homebrew repository ### Core `brew` code related pull request 1. [Fork the Homebrew/brew repository on GitHub](https://github.com/Homebrew/brew/fork). * This creates a personal remote repository that you can push to. This is needed because only Homebrew maintainers have push access to the main repositories. 2. Change to the directory containing your Homebrew installation: cd "$(brew --repository)" 3. Add your pushable forked repository as a new remote: git remote add https://github.com//brew.git * `` is your GitHub username, not your local machine username. ### Formulae related pull request 1. [Fork the Homebrew/homebrew-core repository on GitHub](https://github.com/Homebrew/homebrew-core/fork). * This creates a personal remote repository that you can push to. This is needed because only Homebrew maintainers have push access to the main repositories. 2. Change to the directory containing Homebrew formulae: cd "$(brew --repository homebrew/core)" 3. Add your pushable forked repository as a new remote: git remote add https://github.com//homebrew-core.git * `` is your GitHub username, not your local machine username. ### Cask related pull request 1. [Fork the Homebrew/homebrew-cask repository on GitHub](https://github.com/Homebrew/homebrew-cask/fork). * This creates a personal remote repository that you can push to. This is needed because only Homebrew maintainers have push access to the main repositories. 2. Change to the directory containing Homebrew casks: cd "$(brew --repository homebrew/cask)" 3. Add your pushable forked repository as a new remote: git remote add https://github.com//homebrew-cask.git * `` is your GitHub username, not your local machine username. ## Create your pull request from a new branch To make a new branch and submit it for review, create a GitHub pull request with the following steps: 1. Check out the `master` branch: git checkout master 2. Retrieve new changes to the `master` branch: brew update 3. Create a new branch from the latest `master` branch: git checkout -b origin/master 4. Make your changes. For formulae or casks, use `brew edit` or your favourite text editor, following all the guidelines in the [Formula Cookbook](formula-cookbook) or [Cask Cookbook](cask-cookbook). * If there’s a `bottle do` block in the formula, don’t remove or change it; we’ll update it when we pull your PR. 5. Test your changes by running the following, and ensure they all pass without issue. For changed formulae and casks, make sure you do the `brew audit` step while your changed formula/cask is installed. brew tests brew install --build-from-source brew test brew audit --strict --online 6. [Make a separate commit](formula-cookbook#commit) for each changed formula with `git add` and `git commit`. * Please note that our preferred commit message format for simple version updates is “` `”, e.g. “`source-highlight 3.1.8`”. 7. Upload your branch of new commits to your fork: git push --set-upstream 8. Go to the relevant repository (e.g. , , etc.) and create a pull request to request review and merging of the commits in your pushed branch. Explain why the change is needed and, if fixing a bug, how to reproduce the bug. Make sure you have done each step in the checklist that appears in your new PR. 9. Await feedback or a merge from Homebrew’s maintainers. We typically respond to all PRs within a couple days, but it may take up to a week, depending on the maintainers’ workload. Thank you! ## Following up To respond well to feedback: 1. Ask for clarification of anything you don’t understand and for help with anything you don’t know how to do. 2. Post a comment on your pull request if you’ve provided all the requested changes/information and it hasn’t been merged after a week. Post a comment on your pull request if you’re stuck and need help. * A `needs response` label on a PR means that the Homebrew maintainers need you to respond to previous comments. 3. Keep discussion in the pull request unless requested otherwise (i.e. do not email maintainers privately). 4. Do not continue discussion in closed pull requests. 5. Do not argue with Homebrew maintainers. You may disagree but unless they change their mind, please implement what they request. Ultimately they control what is included in Homebrew, as they have to support any changes that are made. To make changes based on feedback: 1. Check out your branch again: git checkout 2. Make any requested changes and commit them with `git add` and `git commit`. 3. Squash new commits into one commit per formula: git rebase --interactive origin/master * If you are working on a PR for a single formula, `git commit --amend` is a convenient way of keeping your commits squashed as you go. 4. Push to your remote fork’s branch and the pull request: git push --force Once all feedback has been addressed and if it’s a change we want to include (we include most changes), then we’ll add your commit to Homebrew. Note that the PR status may show up as “Closed” instead of “Merged” because of the way we merge contributions. Don’t worry: you will still get author credit in the actual merged commit. Well done, you are now a Homebrew contributor! # Documentation ## Users * [`brew` man-page (command documentation)](manpage) * [Homebrew Blog (news on major updates)](https://brew.sh/blog/) * [Troubleshooting](troubleshooting) * [Installation](installation) * [Frequently Asked Questions](faq) * [Common Issues](common-issues) * [`brew` Shell Completion](shell-completion) * [Homebrew on Linux](homebrew-on-linux) * [Tips and Tricks](tips-n'-tricks) * [Bottles (binary packages)](bottles) * [Taps (third-party repositories)](taps) * [Interesting Taps and Forks](interesting-taps-and-forks) * [Anonymous Aggregate User Behaviour Analytics](analytics) * [Querying `brew`](querying-brew) * [C++ Standard Libraries](c++-standard-libraries) * [MD5 and SHA-1 Deprecation](checksum_deprecation) * [Custom GCC and Cross Compilers](custom-gcc-and-cross-compilers) * [External Commands](external-commands) * [Ruby Gems, Python Eggs and Perl Modules](gems,-eggs-and-perl-modules) * [Python](homebrew-and-python) * [How To Build Software Outside Homebrew With Homebrew `keg_only` dependencies](how-to-build-software-outside-homebrew-with-homebrew-keg-only-dependencies) * [Xcode](xcode) * [Creating a Homebrew Issue](creating-a-homebrew-issue) * [Updating Software in Homebrew](updating-software-in-homebrew) * [Adding Software to Homebrew](adding-software-to-homebrew) * [Kickstarter Supporters](https://docs.brew.sh/Kickstarter-Supporters) ## Contributors * [How To Open A Pull Request (and get it merged)](how-to-open-a-homebrew-pull-request) * [Formula Cookbook](formula-cookbook) * [Cask Cookbook](cask-cookbook) * [Acceptable Formulae](acceptable-formulae) * [Acceptable Casks](acceptable-casks) * [License Guidelines](license-guidelines) * [Formulae Versions](versions) * [Deprecating, Disabling, and Removing Formulae](deprecating-disabling-and-removing-formulae) * [Node for Formula Authors](node-for-formula-authors) * [Python for Formula Authors](python-for-formula-authors) * [`brew livecheck`](brew-livecheck) * [Migrating A Formula To A Tap](migrating-a-formula-to-a-tap) * [Rename A Formula](rename-a-formula) * [Building Against Non-Homebrew Dependencies](building-against-non-homebrew-dependencies) * [How To Create (And Maintain) A Tap](how-to-create-and-maintain-a-tap) * [Brew Test Bot](brew-test-bot) * [Diagram Guidelines](diagram-guidelines) * [Prose Style Guidelines](prose-style-guidelines) * [Type Checking with Sorbet](typechecking) ## Maintainers * [New Maintainer Checklist](https://docs.brew.sh/New-Maintainer-Checklist) * [Maintainers: Avoiding Burnout](https://docs.brew.sh/Maintainers-Avoiding-Burnout) * [Maintainer Guidelines](https://docs.brew.sh/Maintainer-Guidelines) * [Homebrew/brew Maintainer Guide](https://docs.brew.sh/Homebrew-brew-Maintainer-Guide) * [Homebrew/homebrew-core Maintainer Guide](https://docs.brew.sh/Homebrew-homebrew-core-Maintainer-Guide) * [Homebrew/homebrew-cask Maintainer Guide](https://docs.brew.sh/Homebrew-homebrew-cask-Maintainer-Guide) * [Brew Test Bot For Maintainers](https://docs.brew.sh/Brew-Test-Bot-For-Core-Contributors) * [Common Issues for Maintainers](https://docs.brew.sh/Common-Issues-for-Core-Contributors) * [Releases](releases) * [Developer/Internal API Documentation](https://rubydoc.brew.sh) ## Governance * [Homebrew Governance](https://docs.brew.sh/Homebrew-Governance) * [Homebrew Leadership Responsibilities](homebrew-leadership-responsibilities) * [Homebrew Governance Archives](https://docs.brew.sh/Homebrew-Governance-Archives) # Installation Instructions for a supported install of Homebrew are on the [homepage](https://brew.sh). This script installs Homebrew to its preferred prefix (`/usr/local` for macOS Intel, `/opt/homebrew` for Apple Silicon and `/home/linuxbrew/.linuxbrew` for Linux) so that [you don’t need sudo](faq#why-does-homebrew-say-sudo-is-bad) when you `brew install`. It is a careful script; it can be run even if you have stuff installed in the preferred prefix already. It tells you exactly what it will do before it does it too. You have to confirm everything it will do before it starts. ## macOS Requirements * A 64-bit Intel CPU or Apple Silicon CPU 1 * macOS Catalina (10.15) (or higher) 2 * Command Line Tools (CLT) for Xcode (from `xcode-select --install` or ) or [Xcode](https://itunes.apple.com/us/app/xcode/id497799835) 3 * The Bourne-again shell for installation (i.e. `bash`) 4 ## Git Remote Mirroring You can use geolocalized Git mirrors to speed up Homebrew’s installation and `brew update` by setting `HOMEBREW_BREW_GIT_REMOTE` and/or `HOMEBREW_CORE_GIT_REMOTE` in your shell environment with this script: export HOMEBREW_BREW_GIT_REMOTE="..." # put your Git mirror of Homebrew/brew here export HOMEBREW_CORE_GIT_REMOTE="..." # put your Git mirror of Homebrew/homebrew-core here /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" The default Git remote will be used if the corresponding environment variable is unset. ## Alternative Installs ### Linux or Windows 10 Subsystem for Linux Check out [the Homebrew on Linux installation documentation](homebrew-on- linux). ### Untar anywhere Just extract (or `git clone`) Homebrew wherever you want. Just avoid: * Directories with names that contain spaces. Homebrew itself can handle spaces, but many build scripts cannot. * `/tmp` subdirectories because Homebrew gets upset. * `/sw` and `/opt/local` because build scripts get confused when Homebrew is there instead of Fink or MacPorts, respectively. However do yourself a favour and use the installer to install to the default prefix. Some things may not build when installed elsewhere. One of the reasons Homebrew just works relative to the competition is **because** we recommend installing here. _Pick another prefix at your peril!_ mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew or git clone https://github.com/Homebrew/brew homebrew then eval "$(homebrew/bin/brew shellenv)" brew update --force --quiet chmod -R go-w "$(brew --prefix)/share/zsh" ### Multiple installations Create a Homebrew installation wherever you extract the tarball. Whichever `brew` command is called is where the packages will be installed. You can use this as you see fit, e.g. to have a system set of libs in the default prefix and tweaked formulae for development in `~/homebrew`. ### Unattended installation If you want a non-interactive run of the Homebrew installer that doesn’t prompt for passwords (e.g. in automation scripts), prepend [`NONINTERACTIVE=1`](https://github.com/Homebrew/install/#install-homebrew-on- macos-or-linux) to the installation command. ## Uninstallation Uninstallation is documented in the [FAQ](faq). 1 For 32-bit or PPC support see [Tigerbrew](https://github.com/mistydemeo/tigerbrew). 2 10.15 or higher is recommended, while 10.11–10.14 are supported on a best- effort basis. For 10.4–10.6 see [Tigerbrew](https://github.com/mistydemeo/tigerbrew). 3 Most formulae require a compiler. A handful require a full Xcode installation. You can install Xcode, the CLT, or both; Homebrew supports all three configurations. Downloading Xcode may require an Apple Developer account on older versions of Mac OS X. Sign up for free at [Apple’s website](https://developer.apple.com/register/index.action). 4 The one-liner installation method found on [brew.sh](https://brew.sh) requires the Bourne-again shell, i.e. `bash`. Notably, `zsh`, `fish`, `tcsh` and `csh` will not work. # Interesting Taps & Forks A [tap](taps) is Homebrew-speak for a Git repository containing additional formulae. Homebrew has the capability to add (and remove) multiple taps to your local installation with the `brew tap` and `brew untap` commands; run `man brew` in your terminal for usage information. The main repository at , often called `homebrew/core`, is always built-in. Your taps are Git repositories located at `$(brew --repository)/Library/Taps`. ## Unsupported interesting taps * [homebrew-ffmpeg/ffmpeg](https://github.com/homebrew-ffmpeg/homebrew-ffmpeg): A tap for FFmpeg with additional options, including nonfree additions. * [denji/nginx](https://github.com/denji/homebrew-nginx): A tap for NGINX modules, intended for its `nginx-full` formula which includes more module options. * [InstantClientTap/instantclient](https://github.com/InstantClientTap/homebrew-instantclient): A tap for Oracle Instant Client. * [osx-cross/avr](https://github.com/osx-cross/homebrew-avr): GNU AVR toolchain (Libc, compilers and other tools for Atmel MCUs), useful for Arduino hackers and AVR programmers. * [petere/postgresql](https://github.com/petere/homebrew-postgresql): Allows installing multiple PostgreSQL versions in parallel. * [osrf/simulation](https://github.com/osrf/homebrew-simulation): Tools for robotics simulation. * [brewsci/bio](https://github.com/brewsci/homebrew-bio): Bioinformatics formulae. * [davidchall/hep](https://github.com/davidchall/homebrew-hep): High energy physics formulae. * [lifepillar/appleii](https://github.com/lifepillar/homebrew-appleii): Formulae for vintage Apple emulation. * [gromgit/fuse](https://github.com/gromgit/homebrew-fuse): macOS FUSE formulae that are no longer available in `homebrew/core`. * [cloudflare/cloudflare](https://github.com/cloudflare/homebrew-cloudflare): Formulae for the applications by Cloudflare, including curl with HTTP/3 support. ## Unsupported interesting forks * [mistydemeo/tigerbrew](https://github.com/mistydemeo/tigerbrew): Experimental Tiger/Leopard PowerPC version. # License Guidelines We only accept formulae that use a [Debian Free Software Guidelines license](https://wiki.debian.org/DFSGLicenses) or are released into the public domain following [DFSG Guidelines on Public Domain software](https://wiki.debian.org/DFSGLicenses#Public_Domain). ## Specifying a License All licenses are identified by their license identifier from the [SPDX License List](https://spdx.org/licenses/). Specify a license by passing it to the `license` method: license "MIT" The public domain can be indicated using a symbol: license :public_domain If the license for a formula cannot be represented using an SPDX expression: license :cannot_represent ## Complex SPDX License Expressions Some formulae have multiple licenses that need to be combined in different ways. In these cases, a more complex license expression can be used. These expressions are based on the [SPDX License Expression Guidelines](https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license- expressions/). Add a `+` to indicate that the user can choose a later version of the same license: license "EPL-1.0+" GNU licenses (`GPL`, `LGPL`, `AGPL` and `GFDL`) require either the `-only` or the `-or-later` suffix to indicate whether a later version of the license is allowed: license "LGPL-2.1-only" license "GPL-1.0-or-later" Use `:any_of` to indicate that the user can choose which license applies: license any_of: ["MIT", "0BSD"] Use `:all_of` to indicate that the user must comply with multiple licenses: license all_of: ["MIT", "0BSD"] Use `:with` to indicate a license exception: license "MIT" => { with: "LLVM-exception" } These expressions can be nested as needed: license any_of: [ "MIT", :public_domain, all_of: ["0BSD", "Zlib", "Artistic-1.0+"], "Apache-2.0" => { with: "LLVM-exception" }, ] ## Specifying Forbidden Licenses The `HOMEBREW_FORBIDDEN_LICENSES` environment variable can be set to forbid installation of formulae that require or have dependencies that require certain licenses. The `HOMEBREW_FORBIDDEN_LICENSES` should be set to a space separated list of licenses. Use `public_domain` to forbid installation of formulae with a `:public_domain` license. For example, the following forbids installation of `MIT`, `Artistic-1.0` and `:public_domain` licenses: export HOMEBREW_FORBIDDEN_LICENSES="MIT Artistic-1.0 public_domain" In this example Homebrew would refuse to install any formula that specifies the `MIT` license. Homebrew would also forbid installation of any formula that declares a dependency on a formula that specifies `MIT`, even if the original formula has an allowed license. Homebrew interprets complex license expressions and determines whether the licenses allow installation. To continue the above example, Homebrew would not allow installation of a formula with the following license declarations: license any_of: ["MIT", "Artistic-1.0"] license all_of: ["MIT", "0BSD"] Homebrew _would_ allow formulae with the following declaration to be installed: license any_of: ["MIT", "0BSD"] `HOMEBREW_FORBIDDEN_LICENSES` can also forbid future versions of specific licenses. For example, to forbid `Artistic-1.0`, `Artistic-2.0` and any future Artistic licenses, use: export HOMEBREW_FORBIDDEN_LICENSES="Artistic-1.0+" For GNU licenses (such as `GPL`, `LGPL`, `AGPL` and `GFDL`), use `-only` or `-or-later`. For example, the following would forbid `GPL-2.0`, `LGPL-2.1` and `LGPL-3.0` formulae from being installed, but would allow `GPL-3.0` export HOMEBREW_FORBIDDEN_LICENSES="GPL-2.0-only LGPL-2.1-or-later" # Linux CI in `homebrew/core` We currently use Ubuntu 16.04 for bottling in `homebrew/core`. ## Ubuntu vs. other Linux distributions As of 2022, around 77% of our users are using Ubuntu. This is the reason why we have chosen this distribution for our base CI image. We have successfully used Ubuntu for CI since version 14.04. The Ubuntu LTS versions are supported for 5 years. A new LTS version is released every 2 years. Our bottles are compatible with other distributions like Debian/CentOS, even when compiled on Ubuntu. ## Past and next versions We are currently moving our CI to Ubuntu 22.04. This work will probably be done before end of 2022. Moving from Ubuntu 16.04 to Ubuntu 22.04 (and thus skipping version 18.04 and 20.04) took longer than expected. We plan to proceed with regular updates from 2022 onwards. We aim to use the latest Ubuntu LTS version for our CI. We will start using the latest Ubuntu LTS version for our CI no earlier than 3 months after its release and, ideally, no more than 12 months after its release. Distribution | Glibc | GCC | Usage ---|---|---|--- Ubuntu 14.04 | 2.19 | 4 | From 2014 to 2017 Ubuntu 16.04 | 2.23 | 5 | From 2017 to 2022 Ubuntu 22.04 | 2.35 | 11 | From 2022 to 2024 Ubuntu 24.04 | ? | ? | From 2024 to 2026 ## Why always use the latest version? Homebrew is a rolling-release package manager. We try to ship the newest things as quickly as possible, on macOS and Linux. When a formula needs a newer GCC because our host GCC in CI is too old, we needed to make that formula depend on a newer Homebrew GCC. All C++ dependents of that formula immediately acquire a dependency on Homebrew GCC as well. While we have taken the steps to make sure this no longer holds up GCC updates, it still creates a maintenance burden. This problem is more likely for formula which are very actively maintained and try to use newer features of C++. We decided that we shouldn’t have a maintenance burden for formulae which are doing the right thing by staying up to date. It makes a lot of sense for Homebrew maintainers to submit upstream fixes when formulae are not working with newer compilers. It makes a lot less sense for Homebrew maintainers to submit fixes because our host compiler is too old. Note that `glibc` will need to be installed for more users as their `glibc` version will often be too old: disk space is cheap and we have can handle this situation for our users. This situation will often arise when update to a new LTS version and adoption of the new Ubuntu is still low during the first months. For the same reasons as above: we prefer to stay on the bleeding edge and give our users a gentle nudge to think about updating their OS. # brew(1) – The Missing Package Manager for macOS (or Linux) ## SYNOPSIS `brew` `--version` `brew` _`command`_ [`--verbose`|`-v`] [_`options`_] [_`formula`_] … ## DESCRIPTION Homebrew is the easiest and most flexible way to install the UNIX tools Apple didn’t include with macOS. It can also install software not packaged for your Linux distribution to your home directory without requiring `sudo`. ## TERMINOLOGY **formula** : Homebrew package definition built from upstream sources **cask** : Homebrew package definition that installs macOS native applications **keg** : installation destination directory of a given **formula** version e.g. `/usr/local/Cellar/foo/0.1` **rack** : directory containing one or more versioned kegs e.g. `/usr/local/Cellar/foo` **keg-only** : a **formula** is **keg-only** if it is not symlinked into Homebrew’s prefix (e.g. `/usr/local`) **cellar** : directory containing one or more named **racks** e.g. `/usr/local/Cellar` **Caskroom** : directory containing one or more named **casks** e.g. `/usr/local/Caskroom` **external command** : `brew` subcommand defined outside of the Homebrew/brew GitHub repository **tap** : directory (and usually Git repository) of **formulae** , **casks** and/or **external commands** **bottle** : pre-built **keg** poured into the **cellar** /**rack** instead of building from upstream sources ## ESSENTIAL COMMANDS For the full command list, see the COMMANDS section. With `--verbose` or `--debug`, many commands print extra debugging information. Note that these options should only appear after a command. Some command behaviour can be customised with environment variables; see the ENVIRONMENT section. ### `install` _`formula`_ Install _`formula`_. _`formula`_ is usually the name of the formula to install, but it has other syntaxes which are listed in the SPECIFYING FORMULAE section. ### `uninstall` _`formula`_ Uninstall _`formula`_. ### `list` List all installed formulae. ### `search` [_`text`_ |`/`_`text`_`/`] Perform a substring search of cask tokens and formula names for _`text`_. If _`text`_ is flanked by slashes, it is interpreted as a regular expression. The search for _`text`_ is extended online to `homebrew/core` and `homebrew/cask`. If no search term is provided, all locally available formulae are listed. ## COMMANDS ### `analytics` [_`subcommand`_] Control Homebrew’s anonymous aggregate user behaviour analytics. Read more at [https://docs.brew.sh/Analytics](analytics). `brew analytics` [`state`] Display the current state of Homebrew’s analytics. `brew analytics` (`on`|`off`) Turn Homebrew’s analytics on or off respectively. `brew analytics regenerate-uuid` Regenerate the UUID used for Homebrew’s analytics. ### `autoremove` [_`--dry-run`_] Uninstall formulae that were only installed as a dependency of another formula and are now no longer needed. * `-n`, `--dry-run`: List what would be uninstalled, but do not actually uninstall anything. ### `casks` List all locally installable casks including short names. ### `cleanup` [_`options`_] [_`formula`_ |_`cask`_ …] Remove stale lock files and outdated downloads for all formulae and casks, and remove old versions of installed formulae. If arguments are specified, only do this for the given formulae and casks. Removes all downloads more than 120 days old. This can be adjusted with `HOMEBREW_CLEANUP_MAX_AGE_DAYS`. * `--prune`: Remove all cache files older than specified _`days`_. If you want to remove everything, use `--prune=all`. * `-n`, `--dry-run`: Show what would be removed, but do not actually remove anything. * `-s`: Scrub the cache, including downloads for even the latest versions. Note that downloads for any installed formulae or casks will still not be deleted. If you want to delete those too: `rm -rf "$(brew --cache)"` * `--prune-prefix`: Only prune the symlinks and directories from the prefix and remove no other files. ### `commands` [_`--quiet`_] [_`--include-aliases`_] Show lists of built-in and external commands. * `-q`, `--quiet`: List only the names of commands without category headers. * `--include-aliases`: Include aliases of internal commands. ### `completions` [_`subcommand`_] Control whether Homebrew automatically links external tap shell completion files. Read more at [https://docs.brew.sh/Shell-Completion](shell-completion). `brew completions` [`state`] Display the current state of Homebrew’s completions. `brew completions` (`link`|`unlink`) Link or unlink Homebrew’s completions. ### `config`, `--config` Show Homebrew and system configuration info useful for debugging. If you file a bug report, you will be required to provide this information. ### `deps` [_`options`_] [_`formula`_ |_`cask`_ …] Show dependencies for _`formula`_. Additional options specific to _`formula`_ may be appended to the command. When given multiple formula arguments, show the intersection of dependencies for each formula. * `-n`: Sort dependencies in topological order. * `--1`: Only show dependencies one level down, instead of recursing. * `--union`: Show the union of dependencies for multiple _`formula`_ , instead of the intersection. * `--full-name`: List dependencies by their full name. * `--include-build`: Include `:build` dependencies for _`formula`_. * `--include-optional`: Include `:optional` dependencies for _`formula`_. * `--include-test`: Include `:test` dependencies for _`formula`_ (non-recursive). * `--skip-recommended`: Skip `:recommended` dependencies for _`formula`_. * `--include-requirements`: Include requirements in addition to dependencies for _`formula`_. * `--tree`: Show dependencies as a tree. When given multiple formula arguments, show individual trees for each formula. * `--graph`: Show dependencies as a directed graph. * `--dot`: Show text-based graph description in DOT format. * `--annotate`: Mark any build, test, optional, or recommended dependencies as such in the output. * `--installed`: List dependencies for formulae that are currently installed. If _`formula`_ is specified, list only its dependencies that are currently installed. * `--all`: List dependencies for all available formulae. * `--for-each`: Switch into the mode used by the `--all` option, but only list dependencies for each provided _`formula`_ , one formula per line. This is used for debugging the `--installed`/`--all` display mode. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `desc` [_`options`_] _`formula`_ |_`cask`_ |_`text`_ |`/`_`regex`_`/` […] Display _`formula`_ ’s name and one-line description. Formula descriptions are cached; the cache is created on the first search, making that search slower than subsequent ones. * `-s`, `--search`: Search both names and descriptions for _`text`_. If _`text`_ is flanked by slashes, it is interpreted as a regular expression. * `-n`, `--name`: Search just names for _`text`_. If _`text`_ is flanked by slashes, it is interpreted as a regular expression. * `-d`, `--description`: Search just descriptions for _`text`_. If _`text`_ is flanked by slashes, it is interpreted as a regular expression. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `developer` [_`subcommand`_] Control Homebrew’s developer mode. When developer mode is enabled, `brew update` will update Homebrew to the latest commit on the `master` branch instead of the latest stable version along with some other behaviour changes. `brew developer` [`state`] Display the current state of Homebrew’s developer mode. `brew developer` (`on`|`off`) Turn Homebrew’s developer mode on or off respectively. ### `doctor`, `dr` [_`--list-checks`_] [_`--audit-debug`_] [_`diagnostic_check`_ …] Check your system for potential problems. Will exit with a non-zero status if any potential problems are found. Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue. If everything you use Homebrew for is working fine: please don’t worry or file an issue; just ignore this. * `--list-checks`: List all audit methods, which can be run individually if provided as arguments. * `-D`, `--audit-debug`: Enable debugging and profiling of audit methods. ### `fetch` [_`options`_] _`formula`_ |_`cask`_ […] Download a bottle (if available) or source packages for _`formula`_ e and binaries for _`cask`_ s. For files, also print SHA-256 checksums. * `--bottle-tag`: Download a bottle for given tag. * `--HEAD`: Fetch HEAD version instead of stable version. * `-f`, `--force`: Remove a previously cached version and re-fetch. * `-v`, `--verbose`: Do a verbose VCS checkout, if the URL represents a VCS. This is useful for seeing if an existing VCS cache has been updated. * `--retry`: Retry if downloading fails or re-download if the checksum of a previously cached version no longer matches. * `--deps`: Also download dependencies for any listed _`formula`_. * `-s`, `--build-from-source`: Download source packages rather than a bottle. * `--build-bottle`: Download source packages (for eventual bottling) rather than a bottle. * `--force-bottle`: Download a bottle if it exists for the current or newest version of macOS, even if it would not be used during installation. * `--[no-]quarantine`: Disable/enable quarantining of downloads (default: enabled). * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `formulae` List all locally installable formulae including short names. ### `gist-logs` [_`options`_] _`formula`_ Upload logs for a failed build of _`formula`_ to a new Gist. Presents an error message if no logs are found. * `--with-hostname`: Include the hostname in the Gist. * `-n`, `--new-issue`: Automatically create a new issue in the appropriate GitHub repository after creating the Gist. * `-p`, `--private`: The Gist will be marked private and will not appear in listings but will be accessible with its link. ### `home`, `homepage` [_`--formula`_] [_`--cask`_] [_`formula`_ |_`cask`_ …] Open a _`formula`_ or _`cask`_ ’s homepage in a browser, or open Homebrew’s own homepage if no argument is provided. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `info`, `abv` [_`options`_] [_`formula`_ |_`cask`_ …] Display brief statistics for your Homebrew installation. If a _`formula`_ or _`cask`_ is provided, show summary of information about it. * `--analytics`: List global Homebrew analytics data or, if specified, installation and build error data for _`formula`_ (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set). * `--days`: How many days of analytics data to retrieve. The value for _`days`_ must be `30`, `90` or `365`. The default is `30`. * `--category`: Which type of analytics data to retrieve. The value for _`category`_ must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if _`formula`_ is not. The default is `install`. * `--github`: Open the GitHub source page for _`formula`_ and _`cask`_ in a browser. To view the history locally: `brew log -p` _`formula`_ or _`cask`_ * `--json`: Print a JSON representation. Currently the default value for _`version`_ is `v1` for _`formula`_. For _`formula`_ and _`cask`_ use `v2`. See the docs for examples of using the JSON output: [https://docs.brew.sh/Querying-Brew](querying-brew) * `--installed`: Print JSON of formulae that are currently installed. * `--all`: Print JSON of all available formulae. * `--variations`: Include the variations hash in each formula’s JSON output. * `-v`, `--verbose`: Show more verbose analytics data for _`formula`_. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `install` [_`options`_] _`formula`_ |_`cask`_ […] Install a _`formula`_ or _`cask`_. Additional options specific to a _`formula`_ may be appended to the command. Unless `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` is set, `brew upgrade` or `brew reinstall` will be run for outdated dependents and dependents with broken linkage, respectively. Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for the installed formulae or, every 30 days, for all formulae. Unless `HOMEBREW_NO_INSTALL_UPGRADE` is set, `brew install *`formula`*` will upgrade _`formula`_ if it is already installed but outdated. * `-d`, `--debug`: If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory. * `-f`, `--force`: Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask). * `-v`, `--verbose`: Print the verification and postinstall steps. * `--formula`: Treat all named arguments as formulae. * `--ignore-dependencies`: An unsupported Homebrew development flag to skip installing any dependencies of any kind. If the dependencies are not already present, the formula will have issues. If you’re not developing Homebrew, consider adjusting your PATH rather than using this flag. * `--only-dependencies`: Install the dependencies with specified options but do not install the formula itself. * `--cc`: Attempt to compile using the specified _`compiler`_ , which should be the name of the compiler’s executable, e.g. `gcc-7` for GCC 7. In order to use LLVM’s clang, specify `llvm_clang`. To use the Apple-provided clang, specify `clang`. This option will only accept compilers that are provided by Homebrew or bundled with macOS. Please do not file issues if you encounter errors while using this option. * `-s`, `--build-from-source`: Compile _`formula`_ from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available. * `--force-bottle`: Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation. * `--include-test`: Install testing dependencies required to run `brew test` _`formula`_. * `--HEAD`: If _`formula`_ defines it, install the HEAD version, aka. main, trunk, unstable, master. * `--fetch-HEAD`: Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository’s HEAD will only be checked for updates when a new stable or development version has been released. * `--keep-tmp`: Retain the temporary files created during installation. * `--debug-symbols`: Generate debug symbols on build. Source will be retained in a cache directory. * `--build-bottle`: Prepare the formula for eventual bottling during installation, skipping any post-install steps. * `--bottle-arch`: Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on. * `--display-times`: Print install times for each package at the end of the run. * `-i`, `--interactive`: Download and patch _`formula`_ , then open a shell. This allows the user to run `./configure --help` and otherwise determine how to turn the software package into a Homebrew package. * `-g`, `--git`: Create a Git repository, useful for creating patches to the software. * `--overwrite`: Delete files that already exist in the prefix while linking. * `--cask`: Treat all named arguments as casks. * `--[no-]binaries`: Disable/enable linking of helper executables (default: enabled). * `--require-sha`: Require all casks to have a checksum. * `--[no-]quarantine`: Disable/enable quarantining of downloads (default: enabled). * `--skip-cask-deps`: Skip installing cask dependencies. * `--zap`: For use with `brew reinstall --cask`. Remove all files associated with a cask. _May remove files which are shared between applications._ ### `leaves` [_`--installed-on-request`_] [_`--installed-as-dependency`_] List installed formulae that are not dependencies of another installed formula. * `-r`, `--installed-on-request`: Only list leaves that were manually installed. * `-p`, `--installed-as-dependency`: Only list leaves that were installed as dependencies. ### `link`, `ln` [_`options`_] _`installed_formula`_ […] Symlink all of _`formula`_ ’s installed files into Homebrew’s prefix. This is done automatically when you install formulae but can be useful for DIY installations. * `--overwrite`: Delete files that already exist in the prefix while linking. * `-n`, `--dry-run`: List files which would be linked or deleted by `brew link --overwrite` without actually linking or deleting any files. * `-f`, `--force`: Allow keg-only formulae to be linked. * `--HEAD`: Link the HEAD version of the formula if it is installed. ### `list`, `ls` [_`options`_] [_`installed_formula`_ |_`installed_cask`_ …] List all installed formulae and casks. If _`formula`_ is provided, summarise the paths within its current keg. If _`cask`_ is provided, list its artifacts. * `--formula`: List only formulae, or treat all named arguments as formulae. * `--cask`: List only casks, or treat all named arguments as casks. * `--full-name`: Print formulae with fully-qualified names. Unless `--full-name`, `--versions` or `--pinned` are passed, other options (i.e. `-1`, `-l`, `-r` and `-t`) are passed to `ls`(1) which produces the actual output. * `--versions`: Show the version number for installed formulae, or only the specified formulae if _`formula`_ are provided. * `--multiple`: Only show formulae with multiple versions installed. * `--pinned`: List only pinned formulae, or only the specified (pinned) formulae if _`formula`_ are provided. See also `pin`, `unpin`. * `-1`: Force output to be one entry per line. This is the default when output is not to a terminal. * `-l`: List formulae and/or casks in long format. Has no effect when a formula or cask name is passed as an argument. * `-r`: Reverse the order of the formulae and/or casks sort to list the oldest entries first. Has no effect when a formula or cask name is passed as an argument. * `-t`: Sort formulae and/or casks by time modified, listing most recently modified first. Has no effect when a formula or cask name is passed as an argument. ### `log` [_`options`_] [_`formula`_ |_`cask`_] Show the `git log` for _`formula`_ or _`cask`_ , or show the log for the Homebrew repository if no formula or cask is provided. * `-p`, `--patch`: Also print patch from commit. * `--stat`: Also print diffstat from commit. * `--oneline`: Print only one line per commit. * `-1`: Print only one commit. * `-n`, `--max-count`: Print only a specified number of commits. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `migrate` [_`--force`_] [_`--dry-run`_] _`installed_formula`_ […] Migrate renamed packages to new names, where _`formula`_ are old names of packages. * `-f`, `--force`: Treat installed _`formula`_ and provided _`formula`_ as if they are from the same taps and migrate them anyway. * `-n`, `--dry-run`: Show what would be migrated, but do not actually migrate anything. ### `missing` [_`--hide`_`=`] [_`formula`_ …] Check the given _`formula`_ kegs for missing dependencies. If no _`formula`_ are provided, check all kegs. Will exit with a non-zero status if any kegs are found to be missing dependencies. * `--hide`: Act as if none of the specified _`hidden`_ are installed. _`hidden`_ should be a comma-separated list of formulae. ### `options` [_`options`_] [_`formula`_ …] Show install options specific to _`formula`_. * `--compact`: Show all options on a single line separated by spaces. * `--installed`: Show options for formulae that are currently installed. * `--all`: Show options for all available formulae. * `--command`: Show options for the specified _`command`_. ### `outdated` [_`options`_] [_`formula`_ |_`cask`_ …] List installed casks and formulae that have an updated version available. By default, version information is displayed in interactive shells, and suppressed otherwise. * `-q`, `--quiet`: List only the names of outdated kegs (takes precedence over `--verbose`). * `-v`, `--verbose`: Include detailed version information. * `--formula`: List only outdated formulae. * `--cask`: List only outdated casks. * `--json`: Print output in JSON format. There are two versions: `v1` and `v2`. `v1` is deprecated and is currently the default if no version is specified. `v2` prints outdated formulae and casks. * `--fetch-HEAD`: Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository’s HEAD will only be checked for updates when a new stable or development version has been released. * `--greedy`: Also include outdated casks with `auto_updates true` or `version :latest`. * `--greedy-latest`: Also include outdated casks including those with `version :latest`. * `--greedy-auto-updates`: Also include outdated casks including those with `auto_updates true`. ### `pin` _`installed_formula`_ […] Pin the specified _`formula`_ , preventing them from being upgraded when issuing the `brew upgrade` _`formula`_ command. See also `unpin`. ### `postinstall` _`installed_formula`_ […] Rerun the post-install steps for _`formula`_. ### `readall` [_`--aliases`_] [_`--syntax`_] [_`tap`_ …] Import all items from the specified _`tap`_ , or from all installed taps if none is provided. This can be useful for debugging issues across all items when making significant changes to `formula.rb`, testing the performance of loading all items or checking if any current formulae/casks have Ruby issues. * `--aliases`: Verify any alias symlinks in each tap. * `--syntax`: Syntax-check all of Homebrew’s Ruby files (if no `*`tap`*` is passed). ### `reinstall` [_`options`_] _`formula`_ |_`cask`_ […] Uninstall and then reinstall a _`formula`_ or _`cask`_ using the same options it was originally installed with, plus any appended options specific to a _`formula`_. Unless `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` is set, `brew upgrade` or `brew reinstall` will be run for outdated dependents and dependents with broken linkage, respectively. Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for the reinstalled formulae or, every 30 days, for all formulae. * `-d`, `--debug`: If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory. * `-f`, `--force`: Install without checking for previously installed keg-only or non-migrated versions. * `-v`, `--verbose`: Print the verification and postinstall steps. * `--formula`: Treat all named arguments as formulae. * `-s`, `--build-from-source`: Compile _`formula`_ from source even if a bottle is available. * `-i`, `--interactive`: Download and patch _`formula`_ , then open a shell. This allows the user to run `./configure --help` and otherwise determine how to turn the software package into a Homebrew package. * `--force-bottle`: Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation. * `--keep-tmp`: Retain the temporary files created during installation. * `--debug-symbols`: Generate debug symbols on build. Source will be retained in a cache directory. * `--display-times`: Print install times for each formula at the end of the run. * `-g`, `--git`: Create a Git repository, useful for creating patches to the software. * `--cask`: Treat all named arguments as casks. * `--[no-]binaries`: Disable/enable linking of helper executables (default: enabled). * `--require-sha`: Require all casks to have a checksum. * `--[no-]quarantine`: Disable/enable quarantining of downloads (default: enabled). * `--skip-cask-deps`: Skip installing cask dependencies. * `--zap`: For use with `brew reinstall --cask`. Remove all files associated with a cask. _May remove files which are shared between applications._ ### `search`, `-S` [_`options`_] _`text`_ |`/`_`regex`_`/` […] Perform a substring search of cask tokens and formula names for _`text`_. If _`text`_ is flanked by slashes, it is interpreted as a regular expression. The search for _`text`_ is extended online to `homebrew/core` and `homebrew/cask`. * `--formula`: Search online and locally for formulae. * `--cask`: Search online and locally for casks. * `--desc`: Search for formulae with a description matching _`text`_ and casks with a name or description matching _`text`_. * `--pull-request`: Search for GitHub pull requests containing _`text`_. * `--open`: Search for only open GitHub pull requests. * `--closed`: Search for only closed GitHub pull requests. * `--repology`: Search for _`text`_ in the given database. * `--macports`: Search for _`text`_ in the given database. * `--fink`: Search for _`text`_ in the given database. * `--opensuse`: Search for _`text`_ in the given database. * `--fedora`: Search for _`text`_ in the given database. * `--archlinux`: Search for _`text`_ in the given database. * `--debian`: Search for _`text`_ in the given database. * `--ubuntu`: Search for _`text`_ in the given database. ### `shellenv` Print export statements. When run in a shell, this installation of Homebrew will be added to your `PATH`, `MANPATH`, and `INFOPATH`. The variables `HOMEBREW_PREFIX`, `HOMEBREW_CELLAR` and `HOMEBREW_REPOSITORY` are also exported to avoid querying them multiple times. To help guarantee idempotence, this command produces no output when Homebrew’s `bin` and `sbin` directories are first and second respectively in your `PATH`. Consider adding evaluation of this command’s output to your dotfiles (e.g. `~/.profile`, `~/.bash_profile`, or `~/.zprofile`) with: `eval "$(brew shellenv)"` ### `tap` [_`options`_] [_`user`_`/`_`repo`_] [_`URL`_] Tap a formula repository. If no arguments are provided, list all installed taps. With _`URL`_ unspecified, tap a formula repository from GitHub using HTTPS. Since so many taps are hosted on GitHub, this command is a shortcut for `brew tap` _`user`_`/`_`repo`_ `https://github.com/`_`user`_`/homebrew-`_`repo`_. With _`URL`_ specified, tap a formula repository from anywhere, using any transport protocol that `git`(1) handles. The one-argument form of `tap` simplifies but also limits. This two-argument command makes no assumptions, so taps can be cloned from places other than GitHub and using protocols other than HTTPS, e.g. SSH, git, HTTP, FTP(S), rsync. * `--[no-]force-auto-update`: Auto-update tap even if it is not hosted on GitHub. By default, only taps hosted on GitHub are auto-updated (for performance reasons). * `--custom-remote`: Install or change a tap with a custom remote. Useful for mirrors. * `--repair`: Migrate tapped formulae from symlink-based to directory-based structure. * `--list-pinned`: List all pinned taps. ### `tap-info` [_`--installed`_] [_`--json`_] [_`tap`_ …] Show detailed information about one or more _`tap`_ s. If no _`tap`_ names are provided, display brief statistics for all installed taps. * `--installed`: Show information on each installed tap. * `--json`: Print a JSON representation of _`tap`_. Currently the default and only accepted value for _`version`_ is `v1`. See the docs for examples of using the JSON output: [https://docs.brew.sh/Querying-Brew](querying-brew) ### `uninstall`, `remove`, `rm` [_`options`_] _`installed_formula`_ |_`installed_cask`_ […] Uninstall a _`formula`_ or _`cask`_. * `-f`, `--force`: Delete all installed versions of _`formula`_. Uninstall even if _`cask`_ is not installed, overwrite existing files and ignore errors when removing files. * `--zap`: Remove all files associated with a _`cask`_. _May remove files which are shared between applications._ * `--ignore-dependencies`: Don’t fail uninstall, even if _`formula`_ is a dependency of any installed formulae. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `unlink` [_`--dry-run`_] _`installed_formula`_ […] Remove symlinks for _`formula`_ from Homebrew’s prefix. This can be useful for temporarily disabling a formula: `brew unlink` _`formula`_ `&&` _`commands`_ `&& brew link` _`formula`_ * `-n`, `--dry-run`: List files which would be unlinked without actually unlinking or deleting any files. ### `unpin` _`installed_formula`_ […] Unpin _`formula`_ , allowing them to be upgraded by `brew upgrade` _`formula`_. See also `pin`. ### `untap` [_`--force`_] _`tap`_ […] Remove a tapped formula repository. * `-f`, `--force`: Untap even if formulae or casks from this tap are currently installed. ### `update` [_`options`_] Fetch the newest version of Homebrew and all formulae from GitHub using `git`(1) and perform any necessary migrations. * `--merge`: Use `git merge` to apply updates (rather than `git rebase`). * `--auto-update`: Run on auto-updates (e.g. before `brew install`). Skips some slower steps. * `-f`, `--force`: Always do a slower, full update check (even if unnecessary). ### `update-reset` [_`repository`_ …] Fetch and reset Homebrew and all tap repositories (or any specified _`repository`_) using `git`(1) to their latest `origin/HEAD`. _Note:_ this will destroy all your uncommitted or committed changes. ### `upgrade` [_`options`_] [_`outdated_formula`_ |_`outdated_cask`_ …] Upgrade outdated casks and outdated, unpinned formulae using the same options they were originally installed with, plus any appended brew formula options. If _`cask`_ or _`formula`_ are specified, upgrade only the given _`cask`_ or _`formula`_ kegs (unless they are pinned; see `pin`, `unpin`). Unless `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` is set, `brew upgrade` or `brew reinstall` will be run for outdated dependents and dependents with broken linkage, respectively. Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for the upgraded formulae or, every 30 days, for all formulae. * `-d`, `--debug`: If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory. * `-f`, `--force`: Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask). * `-v`, `--verbose`: Print the verification and postinstall steps. * `-n`, `--dry-run`: Show what would be upgraded, but do not actually upgrade anything. * `--formula`: Treat all named arguments as formulae. If no named arguments are specified, upgrade only outdated formulae. * `-s`, `--build-from-source`: Compile _`formula`_ from source even if a bottle is available. * `-i`, `--interactive`: Download and patch _`formula`_ , then open a shell. This allows the user to run `./configure --help` and otherwise determine how to turn the software package into a Homebrew package. * `--force-bottle`: Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation. * `--fetch-HEAD`: Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository’s HEAD will only be checked for updates when a new stable or development version has been released. * `--ignore-pinned`: Set a successful exit status even if pinned formulae are not upgraded. * `--keep-tmp`: Retain the temporary files created during installation. * `--debug-symbols`: Generate debug symbols on build. Source will be retained in a cache directory. * `--display-times`: Print install times for each package at the end of the run. * `--cask`: Treat all named arguments as casks. If no named arguments are specified, upgrade only outdated casks. * `--[no-]binaries`: Disable/enable linking of helper executables (default: enabled). * `--require-sha`: Require all casks to have a checksum. * `--[no-]quarantine`: Disable/enable quarantining of downloads (default: enabled). * `--skip-cask-deps`: Skip installing cask dependencies. * `--greedy`: Also include casks with `auto_updates true` or `version :latest`. * `--greedy-latest`: Also include casks with `version :latest`. * `--greedy-auto-updates`: Also include casks with `auto_updates true`. ### `uses` [_`options`_] _`formula`_ […] Show formulae and casks that specify _`formula`_ as a dependency; that is, show dependents of _`formula`_. When given multiple formula arguments, show the intersection of formulae that use _`formula`_. By default, `uses` shows all formulae and casks that specify _`formula`_ as a required or recommended dependency for their stable builds. * `--recursive`: Resolve more than one level of dependencies. * `--installed`: Only list formulae and casks that are currently installed. * `--include-build`: Include all formulae that specify _`formula`_ as `:build` type dependency. * `--include-test`: Include all formulae that specify _`formula`_ as `:test` type dependency. * `--include-optional`: Include all formulae that specify _`formula`_ as `:optional` type dependency. * `--skip-recommended`: Skip all formulae that specify _`formula`_ as `:recommended` type dependency. * `--formula`: Include only formulae. * `--cask`: Include only casks. ### `--cache` [_`options`_] [_`formula`_ |_`cask`_ …] Display Homebrew’s download cache. See also `HOMEBREW_CACHE`. If _`formula`_ is provided, display the file or directory used to cache _`formula`_. * `-s`, `--build-from-source`: Show the cache file used when building from source. * `--force-bottle`: Show the cache file used when pouring a bottle. * `--bottle-tag`: Show the cache file used when pouring a bottle for the given tag. * `--HEAD`: Show the cache file used when building from HEAD. * `--formula`: Only show cache files for formulae. * `--cask`: Only show cache files for casks. ### `--caskroom` [_`cask`_ …] Display Homebrew’s Caskroom path. If _`cask`_ is provided, display the location in the Caskroom where _`cask`_ would be installed, without any sort of versioned directory as the last path. ### `--cellar` [_`formula`_ …] Display Homebrew’s Cellar path. _Default:_ `$(brew --prefix)/Cellar`, or if that directory doesn’t exist, `$(brew --repository)/Cellar`. If _`formula`_ is provided, display the location in the Cellar where _`formula`_ would be installed, without any sort of versioned directory as the last path. ### `--env`, `environment` [_`--shell`_`=`] [_`--plain`_] [_`formula`_ …] Summarise Homebrew’s build environment as a plain list. If the command’s output is sent through a pipe and no shell is specified, the list is formatted for export to `bash`(1) unless `--plain` is passed. * `--shell`: Generate a list of environment variables for the specified shell, or `--shell=auto` to detect the current shell. * `--plain`: Generate plain output even when piped. ### `--prefix` [_`--unbrewed`_] [_`--installed`_] [_`formula`_ …] Display Homebrew’s install path. _Default:_ * macOS Intel: `/usr/local` * macOS ARM: `/opt/homebrew` * Linux: `/home/linuxbrew/.linuxbrew` If _`formula`_ is provided, display the location where _`formula`_ is or would be installed. * `--unbrewed`: List files in Homebrew’s prefix not installed by Homebrew. * `--installed`: Outputs nothing and returns a failing status code if _`formula`_ is not installed. ### `--repository`, `--repo` [_`tap`_ …] Display where Homebrew’s git repository is located. If _`user`_`/`_`repo`_ are provided, display where tap _`user`_`/`_`repo`_ ’s directory is located. ### `--version`, `-v` Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask (if tapped) to standard output. ## DEVELOPER COMMANDS ### `audit` [_`options`_] [_`formula`_ |_`cask`_ …] Check _`formula`_ for Homebrew coding style violations. This should be run before submitting a new formula or cask. If no _`formula`_ |_`cask`_ are provided, check all locally available formulae and casks and skip style checks. Will exit with a non-zero status if any errors are found. * `--strict`: Run additional, stricter style checks. * `--git`: Run additional, slower style checks that navigate the Git repository. * `--online`: Run additional, slower style checks that require a network connection. * `--installed`: Only check formulae and casks that are currently installed. * `--new`: Run various additional style checks to determine if a new formula or cask is eligible for Homebrew. This should be used when creating new formula and implies `--strict` and `--online`. * `--[no-]appcast`: Audit the appcast. * `--token-conflicts`: Audit for token conflicts. * `--tap`: Check the formulae within the given tap, specified as _`user`_`/`_`repo`_. * `--fix`: Fix style violations automatically using RuboCop’s auto-correct feature. * `--display-cop-names`: Include the RuboCop cop name for each violation in the output. * `--display-filename`: Prefix every line of output with the file or formula name being audited, to make output easy to grep. * `--display-failures-only`: Only display casks that fail the audit. This is the default for formulae. * `--skip-style`: Skip running non-RuboCop style checks. Useful if you plan on running `brew style` separately. Enabled by default unless a formula is specified by name. * `-D`, `--audit-debug`: Enable debugging and profiling of audit methods. * `--only`: Specify a comma-separated _`method`_ list to only run the methods named `audit_`_`method`_. * `--except`: Specify a comma-separated _`method`_ list to skip running the methods named `audit_`_`method`_. * `--only-cops`: Specify a comma-separated _`cops`_ list to check for violations of only the listed RuboCop cops. * `--except-cops`: Specify a comma-separated _`cops`_ list to skip checking for violations of the listed RuboCop cops. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `bottle` [_`options`_] _`installed_formula`_ |_`file`_ […] Generate a bottle (binary package) from a formula that was installed with `--build-bottle`. If the formula specifies a rebuild version, it will be incremented in the generated DSL. Passing `--keep-old` will attempt to keep it at its original value, while `--no-rebuild` will remove it. * `--skip-relocation`: Do not check if the bottle can be marked as relocatable. * `--force-core-tap`: Build a bottle even if _`formula`_ is not in `homebrew/core` or any installed taps. * `--no-rebuild`: If the formula specifies a rebuild version, remove it from the generated DSL. * `--keep-old`: If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL. * `--json`: Write bottle information to a JSON file, which can be used as the value for `--merge`. * `--merge`: Generate an updated bottle block for a formula and optionally merge it into the formula file. Instead of a formula name, requires the path to a JSON file generated with `brew bottle --json` _`formula`_. * `--write`: Write changes to the formula file. A new commit will be generated unless `--no-commit` is passed. * `--no-commit`: When passed with `--write`, a new commit will not generated after writing changes to the formula file. * `--only-json-tab`: When passed with `--json`, the tab will be written to the JSON file but not the bottle. * `--committer`: Specify a committer name and email in `git`’s standard author format. * `--root-url`: Use the specified _`URL`_ as the root of the bottle’s URL instead of Homebrew’s default. * `--root-url-using`: Use the specified download strategy class for downloading the bottle’s URL instead of Homebrew’s default. ### `bump` [_`options`_] [_`formula`_ |_`cask`_ …] Display out-of-date brew formulae and the latest version available. If the returned current and livecheck versions differ or when querying specific formulae, also displays whether a pull request has been opened with the URL. * `--full-name`: Print formulae/casks with fully-qualified names. * `--no-pull-requests`: Do not retrieve pull requests from GitHub. * `--formula`: Check only formulae. * `--cask`: Check only casks. * `--open-pr`: Open a pull request for the new version if there are none already open. * `--limit`: Limit number of package results returned. * `--start-with`: Letter or word that the list of package results should alphabetically follow. ### `bump-cask-pr` [_`options`_] _`cask`_ Create a pull request to update _`cask`_ with a new version. A best effort to determine the _`SHA-256`_ will be made if the value is not supplied by the user. * `-n`, `--dry-run`: Print what would be done rather than doing it. * `--write-only`: Make the expected file modifications without taking any Git actions. * `--commit`: When passed with `--write-only`, generate a new commit after writing changes to the cask file. * `--no-audit`: Don’t run `brew audit` before opening the PR. * `--online`: Run `brew audit --online` before opening the PR. * `--no-style`: Don’t run `brew style --fix` before opening the PR. * `--no-browse`: Print the pull request URL instead of opening in a browser. * `--no-fork`: Don’t try to fork the repository. * `--version`: Specify the new _`version`_ for the cask. * `--message`: Append _`message`_ to the default pull request message. * `--url`: Specify the _`URL`_ for the new download. * `--sha256`: Specify the _`SHA-256`_ checksum of the new download. * `--fork-org`: Use the specified GitHub organization for forking. * `-f`, `--force`: Ignore duplicate open PRs. ### `bump-formula-pr` [_`options`_] [_`formula`_] Create a pull request to update _`formula`_ with a new URL or a new tag. If a _`URL`_ is specified, the _`SHA-256`_ checksum of the new download should also be specified. A best effort to determine the _`SHA-256`_ and _`formula`_ name will be made if either or both values are not supplied by the user. If a _`tag`_ is specified, the Git commit _`revision`_ corresponding to that tag should also be specified. A best effort to determine the _`revision`_ will be made if the value is not supplied by the user. If a _`version`_ is specified, a best effort to determine the _`URL`_ and _`SHA-256`_ or the _`tag`_ and _`revision`_ will be made if both values are not supplied by the user. _Note:_ this command cannot be used to transition a formula from a URL-and- SHA-256 style specification into a tag-and-revision style specification, nor vice versa. It must use whichever style specification the formula already uses. * `-n`, `--dry-run`: Print what would be done rather than doing it. * `--write-only`: Make the expected file modifications without taking any Git actions. * `--commit`: When passed with `--write-only`, generate a new commit after writing changes to the formula file. * `--no-audit`: Don’t run `brew audit` before opening the PR. * `--strict`: Run `brew audit --strict` before opening the PR. * `--online`: Run `brew audit --online` before opening the PR. * `--no-browse`: Print the pull request URL instead of opening in a browser. * `--no-fork`: Don’t try to fork the repository. * `--mirror`: Use the specified _`URL`_ as a mirror URL. If _`URL`_ is a comma-separated list of URLs, multiple mirrors will be added. * `--fork-org`: Use the specified GitHub organization for forking. * `--version`: Use the specified _`version`_ to override the value parsed from the URL or tag. Note that `--version=0` can be used to delete an existing version override from a formula if it has become redundant. * `--message`: Append _`message`_ to the default pull request message. * `--url`: Specify the _`URL`_ for the new download. If a _`URL`_ is specified, the _`SHA-256`_ checksum of the new download should also be specified. * `--sha256`: Specify the _`SHA-256`_ checksum of the new download. * `--tag`: Specify the new git commit _`tag`_ for the formula. * `--revision`: Specify the new commit _`revision`_ corresponding to the specified git _`tag`_ or specified _`version`_. * `-f`, `--force`: Ignore duplicate open PRs. Remove all mirrors if `--mirror` was not specified. * `--python-package-name`: Use the specified _`package-name`_ when finding Python resources for _`formula`_. If no package name is specified, it will be inferred from the formula’s stable URL. * `--python-extra-packages`: Include these additional Python packages when finding resources. * `--python-exclude-packages`: Exclude these Python packages when finding resources. ### `bump-revision` [_`options`_] _`formula`_ […] Create a commit to increment the revision of _`formula`_. If no revision is present, “revision 1” will be added. * `-n`, `--dry-run`: Print what would be done rather than doing it. * `--remove-bottle-block`: Remove the bottle block in addition to bumping the revision. * `--write-only`: Make the expected file modifications without taking any Git actions. * `--message`: Append _`message`_ to the default commit message. ### `bump-unversioned-casks` [_`options`_] _`cask`_ |_`tap`_ […] Check all casks with unversioned URLs in a given _`tap`_ for updates. * `-n`, `--dry-run`: Do everything except caching state and opening pull requests. * `--limit`: Maximum runtime in minutes. * `--state-file`: File for caching state. ### `cat` [_`--formula`_] [_`--cask`_] _`formula`_ |_`cask`_ Display the source of a _`formula`_ or _`cask`_. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. ### `command` _`command`_ […] Display the path to the file being used when invoking `brew` _`cmd`_. ### `contributions` _`email|name`_ [_`--repositories`_`=`] Contributions to Homebrew repos for a user. The first argument is a name (e.g. “BrewTestBot”) or an email address (e.g. “brewtestbot@brew.sh”). * `--repositories`: Specify a comma-separated (no spaces) list of repositories to search. Supported repositories: `brew`, `core`, `cask`, `aliases`, `autoupdate`, `bundle`, `command-not-found`, `test-bot`, `services`, `cask-drivers`, `cask-fonts` and `cask-versions`.Omitting this flag, or specifying `--repositories=all`, will search all repositories. * `--from`: Date (ISO-8601 format) to start searching contributions. * `--to`: Date (ISO-8601 format) to stop searching contributions. ### `create` [_`options`_] _`URL`_ Generate a formula or, with `--cask`, a cask for the downloadable file at _`URL`_ and open it in the editor. Homebrew will attempt to automatically derive the formula name and version, but if it fails, you’ll have to make your own template. The `wget` formula serves as a simple example. For the complete API, see: * `--autotools`: Create a basic template for an Autotools-style build. * `--cask`: Create a basic template for a cask. * `--cmake`: Create a basic template for a CMake-style build. * `--crystal`: Create a basic template for a Crystal build. * `--go`: Create a basic template for a Go build. * `--meson`: Create a basic template for a Meson-style build. * `--node`: Create a basic template for a Node build. * `--perl`: Create a basic template for a Perl build. * `--python`: Create a basic template for a Python build. * `--ruby`: Create a basic template for a Ruby build. * `--rust`: Create a basic template for a Rust build. * `--no-fetch`: Homebrew will not download _`URL`_ to the cache and will thus not add its SHA-256 to the formula for you, nor will it check the GitHub API for GitHub projects (to fill out its description and homepage). * `--HEAD`: Indicate that _`URL`_ points to the package’s repository rather than a file. * `--set-name`: Explicitly set the _`name`_ of the new formula or cask. * `--set-version`: Explicitly set the _`version`_ of the new formula or cask. * `--set-license`: Explicitly set the _`license`_ of the new formula. * `--tap`: Generate the new formula within the given tap, specified as _`user`_`/`_`repo`_. * `-f`, `--force`: Ignore errors for disallowed formula names and names that shadow aliases. ### `dispatch-build-bottle` [_`options`_] _`formula`_ […] Build bottles for these formulae with GitHub Actions. * `--tap`: Target tap repository (default: `homebrew/core`). * `--timeout`: Build timeout (in minutes, default: 60). * `--issue`: If specified, post a comment to this issue number if the job fails. * `--macos`: Version(s) of macOS the bottle should be built for. * `--workflow`: Dispatch specified workflow (default: `dispatch-build-bottle.yml`). * `--upload`: Upload built bottles. * `--linux`: Dispatch bottle for Linux (using GitHub runners). * `--linux-self-hosted`: Dispatch bottle for Linux (using self-hosted runner). * `--linux-wheezy`: Use Debian Wheezy container for building the bottle on Linux. ### `edit` [_`options`_] [_`formula`_ |_`cask`_ …] Open a _`formula`_ or _`cask`_ in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no formula is provided. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. * `--print-path`: Print the file path to be edited, without opening an editor. ### `extract` [_`--version`_`=`] [_`--force`_] _`formula`_ _`tap`_ Look through repository history to find the most recent version of _`formula`_ and create a copy in _`tap`_. Specifically, the command will create the new formula file at _`tap`_`/Formula/`_`formula`_`@`_`version`_`.rb`. If the tap is not installed yet, attempt to install/clone the tap before continuing. To extract a formula from a tap that is not `homebrew/core` use its fully- qualified form of _`user`_`/`_`repo`_`/`_`formula`_. * `--version`: Extract the specified _`version`_ of _`formula`_ instead of the most recent. * `-f`, `--force`: Overwrite the destination formula if it already exists. ### `formula` _`formula`_ […] Display the path where _`formula`_ is located. ### `generate-man-completions` [_`--fail-if-not-changed`_] Generate Homebrew’s manpages and shell completions. * `--fail-if-not-changed`: Return a failing status code if no changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date). ### `install-bundler-gems` [_`--groups`_`=`] Install Homebrew’s Bundler gems. * `--groups`: Installs the specified comma-separated list of gem groups (default: last used). ### `irb` [_`--examples`_] [_`--pry`_] Enter the interactive Homebrew Ruby shell. * `--examples`: Show several examples. * `--pry`: Use Pry instead of IRB. Implied if `HOMEBREW_PRY` is set. ### `linkage` [_`options`_] [_`installed_formula`_ …] Check the library links from the given _`formula`_ kegs. If no _`formula`_ are provided, check all kegs. Raises an error if run on uninstalled formulae. * `--test`: Show only missing libraries and exit with a non-zero status if any missing libraries are found. * `--strict`: Exit with a non-zero status if any undeclared dependencies with linkage are found. * `--reverse`: For every library that a keg references, print its dylib path followed by the binaries that link to it. * `--cached`: Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous `brew linkage` run. ### `livecheck`, `lc` [_`options`_] [_`formula`_ |_`cask`_ …] Check for newer versions of formulae and/or casks from upstream. If no formula or cask argument is passed, the list of formulae and casks to check is taken from `HOMEBREW_LIVECHECK_WATCHLIST` or `~/.brew_livecheck_watchlist`. * `--full-name`: Print formulae/casks with fully-qualified names. * `--tap`: Check formulae/casks within the given tap, specified as _`user`_`/`_`repo`_. * `--all`: Check all available formulae/casks. * `--installed`: Check formulae/casks that are currently installed. * `--newer-only`: Show the latest version only if it’s newer than the formula/cask. * `--json`: Output information in JSON format. * `-q`, `--quiet`: Suppress warnings, don’t print a progress bar for JSON output. * `--formula`: Only check formulae. * `--cask`: Only check casks. ### `pr-automerge` [_`options`_] Find pull requests that can be automatically merged using `brew pr-publish`. * `--tap`: Target tap repository (default: `homebrew/core`). * `--workflow`: Workflow file to use with `brew pr-publish`. * `--with-label`: Pull requests must have this label. * `--without-labels`: Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`). * `--without-approval`: Pull requests do not require approval to be merged. * `--publish`: Run `brew pr-publish` on matching pull requests. * `--no-autosquash`: Instruct `brew pr-publish` to skip automatically reformatting and rewording commits in the pull request to the preferred format. * `--ignore-failures`: Include pull requests that have failing status checks. ### `pr-publish` [_`options`_] _`pull_request`_ […] Publish bottles for a pull request with GitHub Actions. Requires write access to the repository. * `--no-autosquash`: Skip automatically reformatting and rewording commits in the pull request to the preferred format, even if supported on the target tap. * `--branch`: Branch to publish to (default: `master`). * `--message`: Message to include when autosquashing revision bumps, deletions, and rebuilds. * `--tap`: Target tap repository (default: `homebrew/core`). * `--workflow`: Target workflow filename (default: `publish-commit-bottles.yml`). ### `pr-pull` [_`options`_] _`pull_request`_ […] Download and publish bottles, and apply the bottle commit from a pull request with artifacts generated by GitHub Actions. Requires write access to the repository. * `--no-upload`: Download the bottles but don’t upload them. * `--no-commit`: Do not generate a new commit before uploading. * `-n`, `--dry-run`: Print what would be done rather than doing it. * `--clean`: Do not amend the commits from pull requests. * `--keep-old`: If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL. * `--no-autosquash`: Skip automatically reformatting and rewording commits in the pull request to our preferred format. * `--branch-okay`: Do not warn if pulling to a branch besides the repository default (useful for testing). * `--resolve`: When a patch fails to apply, leave in progress and allow user to resolve, instead of aborting. * `--warn-on-upload-failure`: Warn instead of raising an error if the bottle upload fails. Useful for repairing bottle uploads that previously failed. * `--committer`: Specify a committer name and email in `git`’s standard author format. * `--message`: Message to include when autosquashing revision bumps, deletions, and rebuilds. * `--artifact`: Download artifacts with the specified name (default: `bottles`). * `--tap`: Target tap repository (default: `homebrew/core`). * `--root-url`: Use the specified _`URL`_ as the root of the bottle’s URL instead of Homebrew’s default. * `--root-url-using`: Use the specified download strategy class for downloading the bottle’s URL instead of Homebrew’s default. * `--workflows`: Retrieve artifacts from the specified workflow (default: `tests.yml`). Can be a comma-separated list to include multiple workflows. * `--ignore-missing-artifacts`: Comma-separated list of workflows which can be ignored if they have not been run. ### `pr-upload` [_`options`_] Apply the bottle commit and publish bottles to a host. * `--keep-old`: If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL. * `-n`, `--dry-run`: Print what would be done rather than doing it. * `--no-commit`: Do not generate a new commit before uploading. * `--warn-on-upload-failure`: Warn instead of raising an error if the bottle upload fails. Useful for repairing bottle uploads that previously failed. * `--upload-only`: Skip running `brew bottle` before uploading. * `--committer`: Specify a committer name and email in `git`’s standard author format. * `--root-url`: Use the specified _`URL`_ as the root of the bottle’s URL instead of Homebrew’s default. * `--root-url-using`: Use the specified download strategy class for downloading the bottle’s URL instead of Homebrew’s default. ### `prof` [_`--stackprof`_] _`command`_ […] Run Homebrew with a Ruby profiler. For example, `brew prof readall`. * `--stackprof`: Use `stackprof` instead of `ruby-prof` (the default). ### `release` [_`--major`_] [_`--minor`_] Create a new draft Homebrew/brew release with the appropriate version number and release notes. By default, `brew release` will bump the patch version number. Pass `--major` or `--minor` to bump the major or minor version numbers, respectively. The command will fail if the previous major or minor release was made less than one month ago. Requires write access to the Homebrew/brew repository. * `--major`: Create a major release. * `--minor`: Create a minor release. ### `rubocop` Installs, configures and runs Homebrew’s `rubocop`. ### `ruby` [_`options`_] (`-e` _`text`_ |_`file`_) Run a Ruby instance with Homebrew’s libraries loaded. For example, `brew ruby -e "puts :gcc.f.deps"` or `brew ruby script.rb`. * `-r`: Load a library using `require`. * `-e`: Execute the given text string as a script. ### `sh` [_`--env`_`=`] [_`--cmd`_`=`] [_`file`_] Enter an interactive shell for Homebrew’s build environment. Use years-battle- hardened build logic to help your `./configure && make && make install` and even your `gem install` succeed. Especially handy if you run Homebrew in an Xcode-only configuration since it adds tools like `make` to your `PATH` which build systems would not find otherwise. * `--env`: Use the standard `PATH` instead of superenv’s when `std` is passed. * `-c`, `--cmd`: Execute commands in a non-interactive shell. ### `sponsors` Update the list of GitHub Sponsors in the `Homebrew/brew` README. ### `style` [_`options`_] [_`file`_ |_`tap`_ |_`formula`_ |_`cask`_ …] Check formulae or files for conformance to Homebrew style guidelines. Lists of _`file`_ , _`tap`_ and _`formula`_ may not be combined. If none are provided, `style` will run style checks on the whole Homebrew library, including core code and all formulae. * `--fix`: Fix style violations automatically using RuboCop’s auto-correct feature. * `--display-cop-names`: Include the RuboCop cop name for each violation in the output. * `--reset-cache`: Reset the RuboCop cache. * `--formula`: Treat all named arguments as formulae. * `--cask`: Treat all named arguments as casks. * `--only-cops`: Specify a comma-separated _`cops`_ list to check for violations of only the listed RuboCop cops. * `--except-cops`: Specify a comma-separated _`cops`_ list to skip checking for violations of the listed RuboCop cops. ### `tap-new` [_`options`_] _`user`_`/`_`repo`_ Generate the template files for a new tap. * `--no-git`: Don’t initialize a Git repository for the tap. * `--pull-label`: Label name for pull requests ready to be pulled (default: `pr-pull`). * `--branch`: Initialize Git repository and setup GitHub Actions workflows with the specified branch name (default: `main`). * `--github-packages`: Upload bottles to GitHub Packages. ### `test` [_`options`_] _`installed_formula`_ […] Run the test method provided by an installed formula. There is no standard output or return code, but generally it should notify the user if something is wrong with the installed formula. _Example:_ `brew install jruby && brew test jruby` * `-f`, `--force`: Test formulae even if they are unlinked. * `--HEAD`: Test the head version of a formula. * `--keep-tmp`: Retain the temporary files created for the test. * `--retry`: Retry if a testing fails. ### `tests` [_`options`_] Run Homebrew’s unit and integration tests. * `--coverage`: Generate code coverage reports. * `--generic`: Run only OS-agnostic tests. * `--no-compat`: Do not load the compatibility layer when running tests. * `--online`: Include tests that use the GitHub API and tests that use any of the taps for official external commands. * `--byebug`: Enable debugging using byebug. * `--changed`: Only runs tests on files that were changed from the master branch. * `--only`: Run only _`test_script`_`_spec.rb`. Appending `:`_`line_number`_ will start at a specific line. * `--seed`: Randomise tests with the specified _`value`_ instead of a random seed. ### `typecheck`, `tc` [_`options`_] Check for typechecking errors using Sorbet. * `--fix`: Automatically fix type errors. * `-q`, `--quiet`: Silence all non-critical errors. * `--update`: Update RBI files. * `--all`: Regenerate all RBI files rather than just updated gems. * `--suggest-typed`: Try upgrading `typed` sigils. * `--fail-if-not-changed`: Return a failing status code if all gems are up to date and gem definitions do not need a tapioca update. * `--dir`: Typecheck all files in a specific directory. * `--file`: Typecheck a single file. * `--ignore`: Ignores input files that contain the given string in their paths (relative to the input path passed to Sorbet). ### `unbottled` [_`options`_] [_`formula`_ …] Show the unbottled dependents of formulae. * `--tag`: Use the specified bottle tag (e.g. `big_sur`) instead of the current OS. * `--dependents`: Skip getting analytics data and sort by number of dependents instead. * `--all`: Print the number of unbottled and total formulae. ### `unpack` [_`options`_] _`formula`_ […] Unpack the source files for _`formula`_ into subdirectories of the current working directory. * `--destdir`: Create subdirectories in the directory named by _`path`_ instead. * `--patch`: Patches for _`formula`_ will be applied to the unpacked source. * `-g`, `--git`: Initialise a Git repository in the unpacked source. This is useful for creating patches for the software. * `-f`, `--force`: Overwrite the destination directory if it already exists. ### `update-license-data` [_`--fail-if-not-changed`_] Update SPDX license data in the Homebrew repository. * `--fail-if-not-changed`: Return a failing status code if current license data’s version is the same as the upstream. This can be used to notify CI when the SPDX license data is out of date. ### `update-maintainers` Update the list of maintainers in the `Homebrew/brew` README. ### `update-python-resources` [_`options`_] _`formula`_ […] Update versions for PyPI resource blocks in _`formula`_. * `-p`, `--print-only`: Print the updated resource blocks instead of changing _`formula`_. * `-s`, `--silent`: Suppress any output. * `--ignore-non-pypi-packages`: Don’t fail if _`formula`_ is not a PyPI package. * `--version`: Use the specified _`version`_ when finding resources for _`formula`_. If no version is specified, the current version for _`formula`_ will be used. * `--package-name`: Use the specified _`package-name`_ when finding resources for _`formula`_. If no package name is specified, it will be inferred from the formula’s stable URL. * `--extra-packages`: Include these additional packages when finding resources. * `--exclude-packages`: Exclude these packages when finding resources. ### `update-test` [_`options`_] Run a test of `brew update` with a new repository clone. If no options are passed, use `origin/master` as the start commit. * `--to-tag`: Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags. * `--keep-tmp`: Retain the temporary directory containing the new repository clone. * `--commit`: Use the specified _`commit`_ as the start commit. * `--before`: Use the commit at the specified _`date`_ as the start commit. ### `vendor-gems` [_`--update`_`=`] Install and commit Homebrew’s vendored gems. * `--update`: Update all vendored Gems to the latest version. ## GLOBAL CASK OPTIONS These options are applicable to the `install`, `reinstall`, and `upgrade` subcommands with the `--cask` flag. * `--appdir`: Target location for Applications (default: `/Applications`). * `--colorpickerdir`: Target location for Color Pickers (default: `~/Library/ColorPickers`). * `--prefpanedir`: Target location for Preference Panes (default: `~/Library/PreferencePanes`). * `--qlplugindir`: Target location for QuickLook Plugins (default: `~/Library/QuickLook`). * `--mdimporterdir`: Target location for Spotlight Plugins (default: `~/Library/Spotlight`). * `--dictionarydir`: Target location for Dictionaries (default: `~/Library/Dictionaries`). * `--fontdir`: Target location for Fonts (default: `~/Library/Fonts`). * `--servicedir`: Target location for Services (default: `~/Library/Services`). * `--input-methoddir`: Target location for Input Methods (default: `~/Library/Input Methods`). * `--internet-plugindir`: Target location for Internet Plugins (default: `~/Library/Internet Plug-Ins`). * `--audio-unit-plugindir`: Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`). * `--vst-plugindir`: Target location for VST Plugins (default: `~/Library/Audio/Plug-Ins/VST`). * `--vst3-plugindir`: Target location for VST3 Plugins (default: `~/Library/Audio/Plug-Ins/VST3`). * `--screen-saverdir`: Target location for Screen Savers (default: `~/Library/Screen Savers`). * `--language`: Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask’s default language. The default value is the language of your system. ## GLOBAL OPTIONS These options are applicable across multiple subcommands. * `-d`, `--debug`: Display any debugging information. * `-q`, `--quiet`: Make some output more quiet. * `-v`, `--verbose`: Make some output more verbose. * `-h`, `--help`: Show this message. ## OFFICIAL EXTERNAL COMMANDS ### `alias` [_`alias`_ … | _`alias`_ =_`command`_] Show existing aliases. If no aliases are given, print the whole list. * `--edit`: Edit aliases in a text editor. Either one or all aliases may be opened at once. If the given alias doesn’t exist it’ll be pre-populated with a template. ### `autoupdate` _`subcommand`_ [_`interval`_] [_`options`_] An easy, convenient way to automatically update Homebrew. This script will run `brew update` in the background once every 24 hours (by default) until explicitly told to stop, utilising `launchd`. `brew autoupdate start` [_`interval`_] [_`options`_] Start autoupdating either once every `interval` hours or once every 24 hours. Please note the interval has to be passed in seconds, so 12 hours would be `brew autoupdate start 43200`. Pass `--upgrade` or `--cleanup` to automatically run `brew upgrade` and/or `brew cleanup` respectively. Pass `--enable-notification` to send a notification when the autoupdate process has finished successfully. `brew autoupdate stop` Stop autoupdating, but retain plist & logs. `brew autoupdate delete` Cancel the autoupdate, delete the plist and logs. `brew autoupdate status` Prints the current status of this tool. `brew autoupdate version` Output this tool’s current version, and a short changelog. * `--upgrade`: Automatically upgrade your installed formulae. If the Caskroom exists locally Casks will be upgraded as well. Must be passed with `start`. * `--greedy`: Upgrade casks with –greedy (include auto-updating casks). Must be passed with `start`. * `--cleanup`: Automatically clean brew’s cache and logs. Must be passed with `start`. * `--enable-notification`: Send a notification when the autoupdate process has finished successfully, if `terminal-notifier` is installed & found. Must be passed with `start`. * `--immediate`: Starts the autoupdate command immediately, instead of waiting for one interval (24 hours by default) to pass first. Must be passed with `start`. ### `bundle` [_`subcommand`_] Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask, Mac App Store and Whalebrew. `brew bundle` [`install`] Install and upgrade (by default) all dependencies from the `Brewfile`. You can specify the `Brewfile` location using `--file` or by setting the `HOMEBREW_BUNDLE_FILE` environment variable. You can skip the installation of dependencies by adding space-separated values to one or more of the following environment variables: `HOMEBREW_BUNDLE_BREW_SKIP`, `HOMEBREW_BUNDLE_CASK_SKIP`, `HOMEBREW_BUNDLE_MAS_SKIP`, `HOMEBREW_BUNDLE_WHALEBREW_SKIP`, `HOMEBREW_BUNDLE_TAP_SKIP`. `brew bundle` will output a `Brewfile.lock.json` in the same directory as the `Brewfile` if all dependencies are installed successfully. This contains dependency and system status information which can be useful in debugging `brew bundle` failures and replicating a “last known good build” state. You can opt-out of this behaviour by setting the `HOMEBREW_BUNDLE_NO_LOCK` environment variable or passing the `--no-lock` option. You may wish to check this file into the same version control system as your `Brewfile` (or ensure your version control system ignores it if you’d prefer to rely on debugging information from a local machine). `brew bundle dump` Write all installed casks/formulae/images/taps into a `Brewfile` in the current directory. `brew bundle cleanup` Uninstall all dependencies not listed from the `Brewfile`. This workflow is useful for maintainers or testers who regularly install lots of formulae. `brew bundle check` Check if all dependencies are installed from the `Brewfile`. This provides a successful exit code if everything is up-to-date, making it useful for scripting. `brew bundle list` List all dependencies present in the `Brewfile`. By default, only Homebrew dependencies are listed. `brew bundle exec` _`command`_ Run an external command in an isolated build environment based on the `Brewfile` dependencies. This sanitized build environment ignores unrequested dependencies, which makes sure that things you didn’t specify in your `Brewfile` won’t get picked up by commands like `bundle install`, `npm install`, etc. It will also add compiler flags which will help find keg-only dependencies like `openssl`, `icu4c`, etc. * `--file`: Read the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout. * `--global`: Read the `Brewfile` from `~/.Brewfile`. * `-v`, `--verbose`: `install` prints output from commands as they are run. `check` lists all missing dependencies. * `--no-upgrade`: `install` won’t run `brew upgrade` on outdated dependencies. Note they may still be upgraded by `brew install` if needed. * `-f`, `--force`: `dump` overwrites an existing `Brewfile`. `cleanup` actually performs its cleanup operations. * `--cleanup`: `install` performs cleanup operation, same as running `cleanup --force`. * `--no-lock`: `install` won’t output a `Brewfile.lock.json`. * `--all`: `list` all dependencies. * `--formula`: `list` Homebrew dependencies. * `--cask`: `list` Homebrew Cask dependencies. * `--tap`: `list` tap dependencies. * `--mas`: `list` Mac App Store dependencies. * `--whalebrew`: `list` Whalebrew dependencies. * `--describe`: `dump` adds a description comment above each line, unless the dependency does not have a description. * `--no-restart`: `dump` does not add `restart_service` to formula lines. * `--zap`: `cleanup` casks using the `zap` command instead of `uninstall`. ### `command-not-found-init` Print instructions for setting up the command-not-found hook for your shell. If the output is not to a tty, print the appropriate handler script for your shell. ### `services` [_`subcommand`_] Manage background services with macOS’ `launchctl`(1) daemon manager. If `sudo` is passed, operate on `/Library/LaunchDaemons` (started at boot). Otherwise, operate on `~/Library/LaunchAgents` (started at login). [`sudo`] `brew services` [`list`] (`--json`) List information about all managed services for the current user (or root). [`sudo`] `brew services info` (_`formula`_ |`--all`|`--json`) List all managed services for the current user (or root). [`sudo`] `brew services run` (_`formula`_ |`--all`) Run the service _`formula`_ without registering to launch at login (or boot). [`sudo`] `brew services start` (_`formula`_ |`--all`|`--file=`) Start the service _`formula`_ immediately and register it to launch at login (or boot). [`sudo`] `brew services stop` (_`formula`_ |`--all`) Stop the service _`formula`_ immediately and unregister it from launching at login (or boot). [`sudo`] `brew services kill` (_`formula`_ |`--all`) Stop the service _`formula`_ immediately but keep it registered to launch at login (or boot). [`sudo`] `brew services restart` (_`formula`_ |`--all`) Stop (if necessary) and start the service _`formula`_ immediately and register it to launch at login (or boot). [`sudo`] `brew services cleanup` Remove all unused services. * `--file`: Use the service file from this location to `start` the service. * `--all`: Run _`subcommand`_ on all services. * `--json`: Output as JSON. ### `test-bot` [_`options`_] [_`formula`_] Tests the full lifecycle of a Homebrew change to a tap (Git repository). For example, for a GitHub Actions pull request that changes a formula `brew test- bot` will ensure the system is cleaned and set up to test the formula, install the formula, run various tests and checks on it, bottle (package) the binaries and test formulae that depend on it to ensure they aren’t broken by these changes. Only supports GitHub Actions as a CI provider. This is because Homebrew uses GitHub Actions and it’s freely available for public and private use with macOS and Linux workers. * `--dry-run`: Print what would be done rather than doing it. * `--cleanup`: Clean all state from the Homebrew directory. Use with care! * `--skip-setup`: Don’t check if the local system is set up correctly. * `--build-from-source`: Build from source rather than building bottles. * `--build-dependents-from-source`: Build dependents from source rather than testing bottles. * `--junit`: generate a JUnit XML test results file. * `--keep-old`: Run `brew bottle --keep-old` to build new bottles for a single platform. * `--skip-relocation`: Run `brew bottle --skip-relocation` to build new bottles that don’t require relocation. * `--only-json-tab`: Run `brew bottle --only-json-tab` to build new bottles that do not contain a tab. * `--local`: Ask Homebrew to write verbose logs under `./logs/` and set `$HOME` to `./home/` * `--tap`: Use the Git repository of the given tap. Defaults to the core tap for syntax checking. * `--fail-fast`: Immediately exit on a failing step. * `-v`, `--verbose`: Print test step output in real time. Has the side effect of passing output as raw bytes instead of re-encoding in UTF-8. * `--test-default-formula`: Use a default testing formula when not building a tap and no other formulae are specified. * `--root-url`: Use the specified _`URL`_ as the root of the bottle’s URL instead of Homebrew’s default. * `--git-name`: Set the Git author/committer names to the given name. * `--git-email`: Set the Git author/committer email to the given email. * `--publish`: Publish the uploaded bottles. * `--skip-online-checks`: Don’t pass `--online` to `brew audit` and skip `brew livecheck`. * `--skip-dependents`: Don’t test any dependents. * `--skip-recursive-dependents`: Only test the direct dependents. * `--only-cleanup-before`: Only run the pre-cleanup step. Needs `--cleanup`. * `--only-setup`: Only run the local system setup check step. * `--only-tap-syntax`: Only run the tap syntax check step. * `--only-formulae`: Only run the formulae steps. * `--only-formulae-detect`: Only run the formulae detection steps. * `--only-formulae-dependents`: Only run the formulae dependents steps. * `--only-cleanup-after`: Only run the post-cleanup step. Needs `--cleanup`. * `--testing-formulae`: Use these testing formulae rather than running the formulae detection steps. * `--added-formulae`: Use these added formulae rather than running the formulae detection steps. * `--deleted-formulae`: Use these deleted formulae rather than running the formulae detection steps. * `--skipped-or-failed-formulae`: Use these skipped or failed formulae from formulae steps for a formulae dependents step. ### `unalias` _`alias`_ […] Remove aliases. ### `which-formula` [_`--explain`_] _`command`_ […] Prints the formula(e) which provides the given command. * `--explain`: Output explanation of how to get ‘cmd’ by installing one of the providing formulae. ### `which-update` [_`options`_] [_`database`_] Database update for `brew which-formula` * `--stats`: Print statistics about the database contents (number of commands and formulae, list of missing formulae). * `--commit`: Commit the changes using `git`. * `--update-existing`: Update database entries with outdated formula versions. * `--install-missing`: Install and update formulae that are missing from the database and don’t have bottles. * `--max-downloads`: Specify a maximum number of formulae to download and update. ## CUSTOM EXTERNAL COMMANDS Homebrew, like `git`(1), supports external commands. These are executable scripts that reside somewhere in the `PATH`, named `brew-`_`cmdname`_ or `brew-`_`cmdname`_`.rb`, which can be invoked like `brew` _`cmdname`_. This allows you to create your own commands without modifying Homebrew’s internals. Instructions for creating your own commands can be found in the docs: [https://docs.brew.sh/External-Commands](external-commands) ## SPECIFYING FORMULAE Many Homebrew commands accept one or more _`formula`_ arguments. These arguments can take several different forms: * The name of a formula: e.g. `git`, `node`, `wget`. * The fully-qualified name of a tapped formula: Sometimes a formula from a tapped repository may conflict with one in `homebrew/core`. You can still access these formulae by using a special syntax, e.g. `homebrew/dupes/vim` or `homebrew/versions/node4`. * An arbitrary file: Homebrew can install formulae from a local path. It can point to either a formula file or a bottle. Prefix relative paths with `./` to prevent them from being interpreted as a formula or tap name. ## SPECIFYING CASKS Many Homebrew Cask commands accept one or more _`cask`_ arguments. These can be specified the same way as the _`formula`_ arguments described in `SPECIFYING FORMULAE` above. ## ENVIRONMENT Note that environment variables must have a value set to be detected. For example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just `export HOMEBREW_NO_INSECURE_REDIRECT`. * `HOMEBREW_ADDITIONAL_GOOGLE_ANALYTICS_ID` Additional Google Analytics tracking ID to emit user behaviour analytics to. For more information, see: [https://docs.brew.sh/Analytics](analytics) * `HOMEBREW_ARCH` Linux only: Pass this value to a type name representing the compiler’s `-march` option. _Default:_ `native`. * `HOMEBREW_ARTIFACT_DOMAIN` Prefix all download URLs, including those for bottles, with this value. For example, `HOMEBREW_ARTIFACT_DOMAIN=http://localhost:8080` will cause a formula with the URL `https://example.com/foo.tar.gz` to instead download from `http://localhost:8080/https://example.com/foo.tar.gz`. Bottle URLs however, have their domain replaced with this prefix. This results in e.g. `https://ghcr.io/v2/homebrew/core/gettext/manifests/0.21` to instead be downloaded from `http://localhost:8080/v2/homebrew/core/gettext/manifests/0.21` * `HOMEBREW_AUTO_UPDATE_SECS` Run `brew update` once every `HOMEBREW_AUTO_UPDATE_SECS` seconds before some commands, e.g. `brew install`, `brew upgrade` and `brew tap`. Alternatively, disable auto-update entirely with HOMEBREW_NO_AUTO_UPDATE. _Default:_ `300`. * `HOMEBREW_AUTOREMOVE` If set, calls to `brew cleanup` and `brew uninstall` will automatically remove unused formula dependents and if HOMEBREW_NO_INSTALL_CLEANUP is not set, `brew cleanup` will start running `brew autoremove` periodically. * `HOMEBREW_BAT` If set, use `bat` for the `brew cat` command. * `HOMEBREW_BAT_CONFIG_PATH` Use this as the `bat` configuration file. _Default:_ `$HOME/.config/bat/config`. * `HOMEBREW_BAT_THEME` Use this as the `bat` theme for syntax highlighting. _Default:_ `$BAT_THEME`. * `HOMEBREW_BOOTSNAP` If set, use Bootsnap to speed up repeated `brew` calls. A no-op when using Homebrew’s vendored, relocatable Ruby on macOS (as it doesn’t work). * `HOMEBREW_BOTTLE_DOMAIN` Use this URL as the download mirror for bottles. If bottles at that URL are temporarily unavailable, the default bottle domain will be used as a fallback mirror. For example, `HOMEBREW_BOTTLE_DOMAIN=http://localhost:8080` will cause all bottles to download from the prefix `http://localhost:8080/`. If bottles are not available at `HOMEBREW_BOTTLE_DOMAIN` they will be downloaded from the default bottle domain. _Default:_ `https://ghcr.io/v2/homebrew/core`. * `HOMEBREW_BREW_GIT_REMOTE` Use this URL as the Homebrew/brew `git`(1) remote. _Default:_ `https://github.com/Homebrew/brew`. * `HOMEBREW_BROWSER` Use this as the browser when opening project homepages. _Default:_ `$BROWSER` or the OS’s default browser. * `HOMEBREW_CACHE` Use this directory as the download cache. _Default:_ macOS: `$HOME/Library/Caches/Homebrew`, Linux: `$XDG_CACHE_HOME/Homebrew` or `$HOME/.cache/Homebrew`. * `HOMEBREW_CASK_OPTS` Append these options to all `cask` commands. All `--*dir` options, `--language`, `--require-sha`, `--no-quarantine` and `--no-binaries` are supported. For example, you might add something like the following to your `~/.profile`, `~/.bash_profile`, or `~/.zshenv`:\n\n `export HOMEBREW_CASK_OPTS="--appdir=~/Applications --fontdir=/Library/Fonts"` * `HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS` If set, `brew install`, `brew upgrade` and `brew reinstall` will cleanup all formulae when this number of days has passed. _Default:_ `30`. * `HOMEBREW_CLEANUP_MAX_AGE_DAYS` Cleanup all cached files older than this many days. _Default:_ `120`. * `HOMEBREW_COLOR` If set, force colour output on non-TTY outputs. * `HOMEBREW_CORE_GIT_REMOTE` Use this URL as the Homebrew/homebrew-core `git`(1) remote. _Default:_ `https://github.com/Homebrew/homebrew-core`. * `HOMEBREW_CURLRC` If set, do not pass `--disable` when invoking `curl`(1), which disables the use of `curlrc`. * `HOMEBREW_CURL_PATH` Linux only: Set this value to a new enough `curl` executable for Homebrew to use. _Default:_ `curl`. * `HOMEBREW_CURL_RETRIES` Pass the given retry count to `--retry` when invoking `curl`(1). _Default:_ `3`. * `HOMEBREW_CURL_VERBOSE` If set, pass `--verbose` when invoking `curl`(1). * `HOMEBREW_DEVELOPER` If set, tweak behaviour to be more relevant for Homebrew developers (active or budding) by e.g. turning warnings into errors. * `HOMEBREW_DISABLE_LOAD_FORMULA` If set, refuse to load formulae. This is useful when formulae are not trusted (such as in pull requests). * `HOMEBREW_DISPLAY` Use this X11 display when opening a page in a browser, for example with `brew home`. Primarily useful on Linux. _Default:_ `$DISPLAY`. * `HOMEBREW_DISPLAY_INSTALL_TIMES` If set, print install times for each formula at the end of the run. * `HOMEBREW_EDITOR` Use this editor when editing a single formula, or several formulae in the same directory. _Note:_ `brew edit` will open all of Homebrew as discontinuous files and directories. Visual Studio Code can handle this correctly in project mode, but many editors will do strange things in this case. _Default:_ `$EDITOR` or `$VISUAL`. * `HOMEBREW_FAIL_LOG_LINES` Output this many lines of output on formula `system` failures. _Default:_ `15`. * `HOMEBREW_FORBIDDEN_LICENSES` A space-separated list of licenses. Homebrew will refuse to install a formula if it or any of its dependencies has a license on this list. * `HOMEBREW_FORCE_BREWED_CA_CERTIFICATES` If set, always use a Homebrew-installed `ca-certificates` rather than the system version. Automatically set if the system version is too old. * `HOMEBREW_FORCE_BREWED_CURL` If set, always use a Homebrew-installed `curl`(1) rather than the system version. Automatically set if the system version of `curl` is too old. * `HOMEBREW_FORCE_BREWED_GIT` If set, always use a Homebrew-installed `git`(1) rather than the system version. Automatically set if the system version of `git` is too old. * `HOMEBREW_FORCE_VENDOR_RUBY` If set, always use Homebrew’s vendored, relocatable Ruby version even if the system version of Ruby is new enough. * `HOMEBREW_GITHUB_API_TOKEN` Use this personal access token for the GitHub API, for features such as `brew search`. You can create one at . If set, GitHub will allow you a greater number of API requests. For more information, see: _Note:_ Homebrew doesn’t require permissions for any of the scopes, but some developer commands may require additional permissions. * `HOMEBREW_GITHUB_PACKAGES_TOKEN` Use this GitHub personal access token when accessing the GitHub Packages Registry (where bottles may be stored). * `HOMEBREW_DOCKER_REGISTRY_BASIC_AUTH_TOKEN` Use this base64 encoded username and password for authenticating with a Docker registry proxying GitHub Packages. If HOMEBREW_DOCKER_REGISTRY_TOKEN is set, it will be used instead. * `HOMEBREW_DOCKER_REGISTRY_TOKEN` Use this bearer token for authenticating with a Docker registry proxying GitHub Packages. Preferred over HOMEBREW_DOCKER_REGISTRY_TOKEN_BASIC. * `HOMEBREW_GITHUB_PACKAGES_USER` Use this username when accessing the GitHub Packages Registry (where bottles may be stored). * `HOMEBREW_GIT_EMAIL` Set the Git author and committer email to this value. * `HOMEBREW_GIT_NAME` Set the Git author and committer name to this value. * `HOMEBREW_GIT_PATH` Linux only: Set this value to a new enough `git` executable for Homebrew to use. _Default:_ `git`. * `HOMEBREW_INSTALL_BADGE` Print this text before the installation summary of each successful build. _Default:_ The “Beer Mug” emoji. * `HOMEBREW_INSTALL_FROM_API` If set, install formulae and casks in homebrew/core and homebrew/cask taps using Homebrew’s API instead of needing (large, slow) local checkouts of these repositories. _Note:_ Setting HOMEBREW_INSTALL_FROM_API is not compatible with Homebrew’s developer mode so will error (as Homebrew development needs a full clone). * `HOMEBREW_LIVECHECK_WATCHLIST` Consult this file for the list of formulae to check by default when no formula argument is passed to `brew livecheck`. _Default:_ `$HOME/.brew_livecheck_watchlist` * `HOMEBREW_LOGS` Use this directory to store log files. _Default:_ macOS: `$HOME/Library/Logs/Homebrew`, Linux: `$XDG_CACHE_HOME/Homebrew/Logs` or `$HOME/.cache/Homebrew/Logs`. * `HOMEBREW_MAKE_JOBS` Use this value as the number of parallel jobs to run when building with `make`(1). _Default:_ The number of available CPU cores. * `HOMEBREW_NO_ANALYTICS` If set, do not send analytics. For more information, see: [https://docs.brew.sh/Analytics](analytics) * `HOMEBREW_NO_AUTO_UPDATE` If set, do not automatically update before running some commands, e.g. `brew install`, `brew upgrade` and `brew tap`. Alternatively, run this less often by setting HOMEBREW_AUTO_UPDATE_SECS to a value higher than the default. * `HOMEBREW_NO_BOOTSNAP` If set, do not use Bootsnap to speed up repeated `brew` calls. * `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` If set, do not check for broken linkage of dependents or outdated dependents after installing, upgrading or reinstalling formulae. This will result in fewer dependents (and their dependencies) being upgraded or reinstalled but may result in more breakage from running `brew install *`formula`*` or `brew upgrade *`formula`*`. * `HOMEBREW_NO_CLEANUP_FORMULAE` A comma-separated list of formulae. Homebrew will refuse to clean up or autoremove a formula if it appears on this list. * `HOMEBREW_NO_COLOR` If set, do not print text with colour added. _Default:_ `$NO_COLOR`. * `HOMEBREW_NO_COMPAT` If set, disable all use of legacy compatibility code. * `HOMEBREW_NO_EMOJI` If set, do not print `HOMEBREW_INSTALL_BADGE` on a successful build. _Note:_ Will only try to print emoji on OS X Lion or newer. * `HOMEBREW_NO_ENV_HINTS` If set, do not print any hints about changing Homebrew’s behaviour with environment variables. * `HOMEBREW_NO_GITHUB_API` If set, do not use the GitHub API, e.g. for searches or fetching relevant issues after a failed install. * `HOMEBREW_NO_INSECURE_REDIRECT` If set, forbid redirects from secure HTTPS to insecure HTTP. _Note:_ While ensuring your downloads are fully secure, this is likely to cause from-source SourceForge, some GNU & GNOME-hosted formulae to fail to download. * `HOMEBREW_NO_INSTALL_CLEANUP` If set, `brew install`, `brew upgrade` and `brew reinstall` will never automatically cleanup installed/upgraded/reinstalled formulae or all formulae every `HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS` days. Alternatively, HOMEBREW_NO_CLEANUP_FORMULAE allows specifying specific formulae to not clean up. * `HOMEBREW_NO_INSTALL_UPGRADE` If set, `brew install *`formula`*` will not upgrade `*`formula`*` if it is installed but outdated. * `HOMEBREW_PRY` If set, use Pry for the `brew irb` command. * `HOMEBREW_SIMULATE_MACOS_ON_LINUX` If set, running Homebrew on Linux will simulate certain macOS code paths. This is useful when auditing macOS formulae while on Linux. * `HOMEBREW_SSH_CONFIG_PATH` If set, Homebrew will use the given config file instead of `~/.ssh/config` when fetching `git` repos over `ssh`. _Default:_ `$HOME/.ssh/config` * `HOMEBREW_SKIP_OR_LATER_BOTTLES` If set along with `HOMEBREW_DEVELOPER`, do not use bottles from older versions of macOS. This is useful in development on new macOS versions. * `HOMEBREW_SORBET_RUNTIME` If set, enable runtime typechecking using Sorbet. * `HOMEBREW_SVN` Use this as the `svn`(1) binary. _Default:_ A Homebrew-built Subversion (if installed), or the system-provided binary. * `HOMEBREW_TEMP` Use this path as the temporary directory for building packages. Changing this may be needed if your system temporary directory and Homebrew prefix are on different volumes, as macOS has trouble moving symlinks across volumes when the target does not yet exist. This issue typically occurs when using FileVault or custom SSD configurations. _Default:_ macOS: `/private/tmp`, Linux: `/tmp`. * `HOMEBREW_UPDATE_REPORT_ALL_FORMULAE` If set, `brew update` lists changes to all formulae and cask files rather than only showing when they are new and not installed or outdated and installed. * `HOMEBREW_UPDATE_TO_TAG` If set, always use the latest stable tag (even if developer commands have been run). * `HOMEBREW_VERBOSE` If set, always assume `--verbose` when running commands. * `HOMEBREW_DEBUG` If set, always assume `--debug` when running commands. * `HOMEBREW_VERBOSE_USING_DOTS` If set, verbose output will print a `.` no more than once a minute. This can be useful to avoid long-running Homebrew commands being killed due to no output. * `all_proxy` Use this SOCKS5 proxy for `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew. * `ftp_proxy` Use this FTP proxy for `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew. * `http_proxy` Use this HTTP proxy for `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew. * `https_proxy` Use this HTTPS proxy for `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew. * `no_proxy` A comma-separated list of hostnames and domain names excluded from proxying by `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew. * `SUDO_ASKPASS` If set, pass the `-A` option when calling `sudo`(8). ## USING HOMEBREW BEHIND A PROXY Set the `http_proxy`, `https_proxy`, `all_proxy`, `ftp_proxy` and/or `no_proxy` environment variables documented above. For example, to use an unauthenticated HTTP or SOCKS5 proxy: export http_proxy=http://$HOST:$PORT export all_proxy=socks5://$HOST:$PORT And for an authenticated HTTP proxy: export http_proxy=http://$USER:$PASSWORD@$HOST:$PORT ## SEE ALSO Homebrew Documentation: Homebrew API: `git`(1), `git-log`(1) ## AUTHORS Homebrew’s Project Leader is Mike McQuaid. Homebrew’s Project Leadership Committee is Issy Long, Jonathan Chang, Mike McQuaid, Misty De Méo and Sean Molenaar. Homebrew’s Technical Steering Committee is Bo Anderson, FX Coudert, Michka Popoff, Mike McQuaid and Rylan Polster. Homebrew’s other current maintainers are Alexander Bayandin, Bevan Kay, Branch Vincent, Caleb Xu, Carlo Cabrera, Daniel Nachun, Dawid Dziurla, Dustin Rodrigues, Eric Knibbe, George Adams, Markus Reiter, Maxim Belkin, Miccal Matthews, Michael Cho, Nanda H Krishna, Randall, Rui Chen, Sam Ford, Shaun Jackman, Steve Peters, Thierry Moisan and Vítor Galvão. Former maintainers with significant contributions include Claudia Pellegrino, Seeker, William Woodruff, Jan Viljanen, JCount, commitay, Dominyk Tiller, Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski, Alyssa Ross, ilovezfs, Chongyu Zhu and Homebrew’s creator: Max Howell. ## BUGS See our issues on GitHub: * **Homebrew/brew** : * **Homebrew/homebrew-core** : * **Homebrew/homebrew-cask** : # Migrating A Formula To A Tap There are times when we may wish to migrate a formula from one tap into another tap. To do this: 1. Create a pull request to the new tap adding the formula file as-is from the original tap. Fix any test failures that may occur due to the stricter requirements for new formulae than existing formula (e.g. `brew audit --strict` must pass for that formula). 2. Create a pull request to the original tap deleting the formula file and add it to `tap_migrations.json` with a commit message like `gv: migrate to homebrew/core`. 3. Put a link for each pull request in the other pull request so the maintainers can merge them both at once. Congratulations, you’ve moved a formula to a tap! For Homebrew maintainers, formulae should only ever be migrated into and within the Homebrew organisation (e.g. from Homebrew/core to Homebrew/cask, or from a third-party tap to Homebrew/core), and never out of it. # Node for Formula Authors This document explains how to successfully use Node and npm in a Node module based Homebrew formula. ## Running `npm install` Homebrew provides two helper methods in a `Language::Node` module: `std_npm_install_args` and `local_npm_install_args`. They both set up the correct environment for npm and return arguments for `npm install` for their specific use cases. Your formula should use these instead of invoking `npm install` explicitly. The syntax for a standard Node module installation is: system "npm", "install", *Language::Node.std_npm_install_args(libexec) where `libexec` is the destination prefix (usually the `libexec` variable). ## Download URL If the Node module is also available on the npm registry, we prefer npm hosted release tarballs over GitHub (or elsewhere) hosted source tarballs. The advantages of these tarballs are that they don’t include the files from the `.npmignore` (such as tests) resulting in a smaller download size and that any possible transpilation step is already done (e.g. no need to compile CoffeeScript files as a build step). The npm registry URLs usually have the format of: https://registry.npmjs.org//-/-.tgz Alternatively you could `curl` the JSON at `https://registry.npmjs.org/` and look for the value of `versions[].dist.tarball` for the correct tarball URL. ## Dependencies Node modules which are compatible with the latest Node version should declare a dependency on the `node` formula. depends_on "node" If your formula requires being executed with an older Node version you should use one of the versioned node formulae (e.g. `node@12`). ### Special requirements for native addons If your Node module is a native addon or has a native addon somewhere in its dependency tree you have to declare an additional dependency. Since the compilation of the native addon results in an invocation of `node-gyp` we need an additional build time dependency on `"python"` (because GYP depends on Python). depends_on "python" => :build Also note that such a formula would only be compatible with the same Node major version it originally was compiled with. This means that we need to revision every formula with a Node native addon with every major version bump of the `node` formula. To make sure we don’t overlook your formula on a Node major version bump, write a meaningful test which would fail in such a case (invoked with an ABI-incompatible Node version). ## Installation Node modules should be installed to `libexec`. This prevents the Node modules from contaminating the global `node_modules`, which is important so that npm doesn’t try to manage Homebrew-installed Node modules. In the following we distinguish between two types of Node modules installed using formulae: * formulae for standard Node modules compatible with npm’s global module format which should use `std_npm_install_args` (like [`azure-cli`](https://github.com/Homebrew/homebrew-core/blob/0f3b27d252b8112c744e0460d871cfe1def6b993/Formula/azure-cli.rb) or [`webpack`](https://github.com/Homebrew/homebrew-core/blob/6282879973d569962e63da7c81ac4623e1a8336b/Formula/webpack.rb)) * formulae where the `npm install` call is not the only required install step (e.g. need to also compile non-JavaScript sources) which have to use `local_npm_install_args` (like [`elixirscript`](https://github.com/Homebrew/homebrew-core/blob/4bb491b7b246830aed57b97348a17e9401374978/Formula/elixirscript.rb) or [`grunt-cli`](https://github.com/Homebrew/homebrew-core/blob/93be1840908adb2f9ee8c48c66586ee6327480e3/Formula/grunt-cli.rb)) What both methods have in common is that they are setting the correct environment for using npm inside Homebrew and are returning the arguments for invoking `npm install` for their specific use cases. This includes fixing an important edge case with the npm cache (caused by Homebrew’s redirection of `HOME` during the build and test process) by using our own custom `npm_cache` inside `HOMEBREW_CACHE`, which would otherwise result in very long build times and high disk space usage. To use them you have to require the Node language module at the beginning of your formula file with: require "language/node" ### Installing global style modules with `std_npm_install_args` to `libexec` In your formula’s `install` method, simply `cd` to the top level of your Node module if necessary and then use `system` to invoke `npm install` with `Language::Node.std_npm_install_args` like: system "npm", "install", *Language::Node.std_npm_install_args(libexec) This will install your Node module in npm’s global module style with a custom prefix to `libexec`. All your modules’ executables will be automatically resolved by npm into `libexec/bin` for you, which is not symlinked into Homebrew’s prefix. We need to make sure these are installed. To do this we need to symlink all executables to `bin` with: bin.install_symlink Dir["#{libexec}/bin/*"] ### Installing module dependencies locally with `local_npm_install_args` In your formula’s `install` method, do any installation steps which need to be done before the `npm install` step and then `cd` to the top level of the included Node module. Then, use `system` with `Language::Node.local_npm_install_args` to invoke `npm install` like: system "npm", "install", *Language::Node.local_npm_install_args This will install all of your Node modules dependencies to your local build path. You can now continue with your build steps and take care of the installation into the Homebrew `prefix` on your own, following the [general Homebrew formula instructions](formula-cookbook). ## Example Installing a standard Node module based formula would look like this: require "language/node" class Foo < Formula desc "..." homepage "..." url "https://registry.npmjs.org/foo/-/foo-1.4.2.tgz" sha256 "..." depends_on "node" # uncomment if there is a native addon inside the dependency tree # depends_on "python" => :build def install system "npm", "install", *Language::Node.std_npm_install_args(libexec) bin.install_symlink Dir["#{libexec}/bin/*"] end test do # add a meaningful test here end end ## Tooling You can use [homebrew-npm-noob](https://github.com/zmwangx/homebrew-npm-noob) to automatically generate a formula like the example above for an npm package. # Prose Style Guidelines This is a set of style and usage guidelines for Homebrew’s prose documentation aimed at users, contributors, and maintainers (as opposed to executable computer code). It applies to documents like those in `docs` in the `Homebrew/brew` repository, announcement emails, and other communications with the Homebrew community. This does not apply to any Ruby or other computer code. You can use it to inform technical documentation extracted from computer code, like embedded man pages, but it’s just a suggestion there. ## Goals and audience The primary goal of Homebrew’s prose documents is communicating with its community of users and contributors. “Users” includes “contributors” here; wherever you see “users” you can substitute “users and contributors”. Understandability is more important than any particular style guideline. Users take precedence over maintainers, except in specifically maintainer- focused documents. Homebrew’s audience includes users with a wide range of education and experience, and users for whom English is not a native language. We aim to support as many of those users as feasible. We strive for “correct” but not “fancy” usage. Think newspaper article, not academic paper. This is a set of guidelines to be applied using human judgement, not a set of hard and fast rules. It is like [The Economist’s Style Guide](https://web.archive.org/web/20170830001125/https://www.economist.com/styleguide/introduction) or [Garner’s Modern American Usage](https://en.wikipedia.org/wiki/Garner's_Modern_American_Usage). It is less like the [Ruby Style Guide](https://github.com/rubocop-hq/ruby-style- guide#the-ruby-style-guide). All guidelines here are open to interpretation and discussion. 100% conformance to these guidelines is _not_ a goal. The intent of this document is to help authors make decisions about clarity, style, and consistency. It is not to help settle arguments about who knows English better. Don’t use this document to be a jerk. ## Guidelines We prefer: ### Style and usage * British/Commonwealth English over American English, in general * “e.g.” and “i.e.”: Go ahead and use “e.g.” or “i.e.” instead of spelling them out. Don’t worry about putting a comma after them. * “e.g.” means “for example”; “i.e.” means “that is” * Offset nontrivial subordinate clauses with commas ### Personal pronouns * We respect all people’s choice of personal pronouns * Singular “they” when someone’s gender is unknown * Avoid gender-specific language when not necessary ### Structure and markup * Title Case in `h1` headings; sentence case in all other headings * Periods at the ends of list items where most items in that list are complete sentences * More generally, parallel list item structure * Capitalise all list items if you want, even if they’re not complete sentences; just be consistent within each list, and preferably, throughout the whole page * Use a subordinate list item instead of dropping a multi-sentence paragraph-long item into a list of sentence fragments * Prefer Markdown over other markup formats unless their specific features are needed * GitHub Flavoured Markdown. GitHub’s implementation is the standard, period. ### Typographical conventions * Literal text in commands and code is styled in `fixed width font` * Placeholders inside code snippets are marked up with `<...>` brackets * e.g. `git remote add https://github.com//homebrew-core.git` * Names of commands like `git` and `brew` are styled in `fixed width font` * No “$” with environment variables mentioned outside code snippets * e.g. “Set `BLAH` to 5”, not “Set `$BLAH` to 5” * One space after periods, not two * Capitalised proper nouns * We do not defer to extensive nonstandard capitalisation, typesetting, or other styling of brand names, aside from the normal capitalisation of proper nouns and simple internal capitalisation * No “TM”, ™, SM, ©, ®, or other explicit indicators of rights ownership or trademarks; we take these as understood when the brand name is mentioned * Tap names like `homebrew/core` are styled in `fixed width font`. Repository names may be styled in either fixed width font like “`Homebrew/homebrew-core`”, as links like “[Homebrew/homebrew-core](https://github.com/homebrew/homebrew-core)”, or regular text like “Homebrew/homebrew-core”, based on which looks best for a given use. * But be consistent within a single document * Capitalise repository names to match the user and repository names on GitHub. Keep tap names in lower case. * Commas * No Oxford commas * Prefer a “loose” comma style: “when in doubt, leave it out” unless needed for clarity ### Terminology, words, and word styling * “pull request”, not “Pull Request” * “check out” is the verb; “checkout” is the noun * Spell out certain technical words * “repository”, not “repo” * When abbreviating, introduce the abbreviation with the first usage in any document * Some abbreviations (near-universally understood among our user base) are fine, though. * “Mac” is fine; “Macintosh” isn’t necessary * “macOS” for all versions, “OS X” or “Mac OS X” when describing specific older versions * “RuboCop”, not “Rubocop” * A pull request is made “on” a repository; that repository is “at” a URL ## How to use these guidelines Refer to these guidelines to make decisions about style and usage in your own writing for Homebrew documents and communication. PRs that fix style and usage throughout a document or multiple documents are okay and encouraged. PRs for just one or two style changes are a bit much. Giving style and usage feedback on a PR or commit that involves documents is okay and encouraged. But keep in mind that these are just guidelines, and for any change, the author may have made a deliberate choice to break these rules in the interest of understandability or aesthetics. # Python for Formula Authors This document explains how to successfully use Python in a Homebrew formula. Homebrew draws a distinction between Python **applications** and Python **libraries**. The difference is that users generally do not care that applications are written in Python; it is unusual that a user would expect to be able to `import foo` after installing an application. Examples of applications are [`ansible`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/ansible.rb) and [`jrnl`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/jrnl.rb). Python libraries exist to be imported by other Python modules; they are often dependencies of Python applications. They are usually no more than incidentally useful in a terminal. Examples of libraries are [`py2cairo`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/py2cairo.rb) and the bindings that are installed by [`protobuf`](https://github.com/Homebrew/homebrew- core/blob/HEAD/Formula/protobuf.rb). Bindings are a special case of libraries that allow Python code to interact with a library or application implemented in another language. Homebrew is happy to accept applications that are built in Python, whether the apps are available from PyPI or not. Homebrew generally won’t accept libraries that can be installed correctly with `pip install foo`. Bindings may be installed for packages that provide them, especially if equivalent functionality isn’t available through pip. Applications should unconditionally bundle all of their Python-language dependencies and libraries and should install any unsatisfied dependencies; these strategies are discussed in depth in the following sections. ## Applications ### Python declarations Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python@3.x"`. These apps **must** work with the current Homebrew Python 3.x formula. Applications that are compatible with Python 2 **should** use the Apple- provided system Python in `/usr/bin` on systems that provide Python 2.7. No explicit Python dependency is needed since `/usr/bin` is always in `PATH` for Homebrew formulae. ### Installing Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app’s Python modules from contaminating the system site-packages and vice versa. All of the Python module dependencies of the application (and their dependencies, recursively) should be declared as `resource`s in the formula and installed into the virtualenv, as well. Each dependency should be explicitly specified; please do not rely on `setup.py` or `pip` to perform automatic dependency resolution, for the [reasons described here](acceptable- formulae#we-dont-like-install-scripts-that-download-unversioned-things). You can use `brew update-python-resources` to help you write resource stanzas. To use it, simply run `brew update-python-resources `. Sometimes, `brew update-python-resources` won’t be able to automatically update the resources. If this happens, try running `brew update-python-resources --print- only ` to print the resource stanzas instead of applying the changes directly to the file. You can then copy and paste resources as needed. If using `brew update-python-resources` doesn’t work, you can use [homebrew- pypi-poet](https://pypi.python.org/pypi/homebrew-pypi-poet) to help you write resource stanzas. To use it, set up a virtualenv and install your package and all its dependencies. Then, `pip install homebrew-pypi-poet` into the same virtualenv. Running `poet some_package` will generate the necessary resource stanzas. You can do this like: # Use a temporary directory for the virtual environment cd "$(mktemp -d)" # Create and source a new virtual environment in the venv/ directory python3 -m venv venv source venv/bin/activate # Install the package of interest as well as homebrew-pypi-poet pip install some_package homebrew-pypi-poet poet some_package # Destroy the virtual environment deactivate rm -rf venv Homebrew provides helper methods for instantiating and populating virtualenvs. You can use them by putting `include Language::Python::Virtualenv` at the top of the `Formula` class definition. For most applications, all you will need to write is: def install virtualenv_install_with_resources end This is exactly the same as writing: def install # Create a virtualenv in `libexec`. If your app needs Python 3, make sure that # `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python3")`. venv = virtualenv_create(libexec) # Install all of the resources declared on the formula into the virtualenv. venv.pip_install resources # `pip_install_and_link` takes a look at the virtualenv's bin directory # before and after installing its argument. New scripts will be symlinked # into `bin`. `pip_install_and_link buildpath` will install the package # that the formula points to, because buildpath is the location where the # formula's tarball was unpacked. venv.pip_install_and_link buildpath end ### Example Installing a formula with dependencies will look like this: class Foo < Formula include Language::Python::Virtualenv url "..." resource "six" do url "https://pypi.python.org/packages/source/s/six/six-1.9.0.tar.gz" sha256 "e24052411fc4fbd1f672635537c3fc2330d9481b18c0317695b46259512c91d5" end resource "parsedatetime" do url "https://pypi.python.org/packages/source/p/parsedatetime/parsedatetime-1.4.tar.gz" sha256 "09bfcd8f3c239c75e77b3ff05d782ab2c1aed0892f250ce2adf948d4308fe9dc" end def install virtualenv_install_with_resources end end You can also use the more verbose form and request that specific resources be installed: def install venv = virtualenv_create(libexec) %w[six parsedatetime].each do |r| venv.pip_install resource(r) end venv.pip_install_and_link buildpath end in case you need to do different things for different resources. ## Bindings To add bindings for Python 3, please add `depends_on "python@3.x"` to work with the current Homebrew Python 3.x formula. Build Python 2 bindings with the system Python by default (don’t add an option) and they should be usable with any binary-compatible Python. If that isn’t the case, it’s an upstream bug; [here’s some advice for resolving it](https://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). ### Dependencies Bindings should follow the same advice for Python module dependencies as libraries; see below for more. ### Installing bindings If the bindings are installed by invoking a `setup.py`, do something like: cd "source/python" do system Formula["python@3.x"].opt_bin/"python3", *Language::Python.setup_install_args(prefix) end If the configure script takes a `--with-python` flag, it usually will not need extra help finding Python. If the `configure` and `make` scripts do not want to install into the Cellar, sometimes you can: 1. call `./configure --without-python` (or a similar named option) 2. `cd` into the directory containing the Python bindings 3. call `setup.py` with `system` and `Language::Python.setup_install_args` (as described above) Sometimes we have to edit a `Makefile` on-the-fly to use our prefix for the Python bindings using Homebrew’s [`inreplace`](formula-cookbook#inreplace) helper method. ## Libraries ### Python declarations Libraries built for Python 3 should include `depends_on "python@3.x"`, which will bottle against Homebrew’s Python 3.x. Python 2.x libraries must function when they are installed against either the system Python or brewed Python. Python 2 libraries need a `uses_from_macos "python@2"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it’s an upstream bug; [here’s some advice for resolving it](https://blog.tim-smith.us/2015/09/python-extension-modules- os-x/). ### Installing Libraries may be installed to `libexec` and added to `sys.path` by writing a `.pth` file (named like “homebrew-foo.pth”) to the `prefix` site-packages. This simplifies the ensuing drama if `pip` is accidentally used to upgrade a Homebrew-installed package and prevents the accumulation of stale .pyc files in Homebrew’s site-packages. Most formulae presently just install to `prefix`. ### Dependencies The dependencies of libraries must be installed so that they are importable. To minimise the potential for linking conflicts, dependencies should be installed to `libexec/` and added to `sys.path` by writing a second `.pth` file (named like “homebrew-foo-dependencies.pth”) to the `prefix` site- packages. ## Further down the rabbit hole Additional commentary that explains why Homebrew does some of the things it does. ### setuptools vs. distutils vs. pip Distutils is a module in the Python standard library that provides developers a basic package management API. Setuptools is a module distributed outside the standard library that extends distutils. It is a convention that Python packages provide a `setup.py` that calls the `setup()` function from either distutils or setuptools. Setuptools provides the `easy_install` command, which is an end-user package management tool that fetches and installs packages from PyPI, the Python Package Index. `pip` is another, newer end-user package management tool, which is also provided outside the standard library. While pip supplants `easy_install`, pip does not replace the other functionality of the setuptools module. Distutils and pip use a “flat” installation hierarchy that installs modules as individual files under site-packages while `easy_install` installs zipped eggs to site-packages instead. Distribute (not to be confused with distutils) is an obsolete fork of setuptools. Distlib is a package maintained outside the standard library which is used by pip for some low-level packaging operations and is not relevant to most `setup.py` users. ### Running `setup.py` In the event that a formula needs to interact with `setup.py` instead of calling `pip`, Homebrew provides a helper method, `Language::Python.setup_install_args`, which returns useful arguments for invoking `setup.py`. Your formula should use this instead of invoking `setup.py` explicitly. The syntax is: system Formula["python@3.x"].opt_bin/"python3", *Language::Python.setup_install_args(prefix) where `prefix` is the destination prefix (usually `libexec` or `prefix`). ### What is `--single-version-externally-managed`? `--single-version-externally-managed` (“SVEM”) is a setuptools-only [argument to `setup.py install`](https://setuptools.readthedocs.io/en/latest/setuptools.html?#install- run-easy-install-or-old-style-installation). The primary effect of SVEM is to use distutils to perform the install instead of using setuptools’ `easy_install`. `easy_install` does a few things that we need to avoid: * fetches and installs dependencies * upgrades dependencies in `sys.path` in-place * writes `.pth` and `site.py` files which aren’t useful for us and cause link conflicts Setuptools requires that SVEM is used in conjunction with `--record`, which provides a list of files that can later be used to uninstall the package. We don’t need or want this because Homebrew can manage uninstallation but since setuptools demands it we comply. The Homebrew convention is to call the record file “installed.txt”. Detecting whether a `setup.py` uses `setup()` from setuptools or distutils is difficult, but we always need to pass this flag to setuptools-based scripts. `pip` faces the same problem that we do and forces `setup()` to use the setuptools version by loading a shim around `setup.py` that imports setuptools before doing anything else. Since setuptools monkey-patches distutils and replaces its `setup` function, this provides a single, consistent interface. We have borrowed this code and use it in `Language::Python.setup_install_args`. ### `--prefix` vs `--root` `setup.py` accepts a slightly bewildering array of installation options. The correct switch for Homebrew is `--prefix`, which automatically sets the `--install-foo` family of options using sane POSIX-y values. `--root` [is used](https://mail.python.org/pipermail/distutils- sig/2010-November/017099.html) when installing into a prefix that will not become part of the final installation location of the files, like when building a .rpm or binary distribution. When using a `setup.py`-based setuptools, `--root` has the side effect of activating `--single-version- externally-managed`. It is not safe to use `--root` with an empty `--prefix` because the `root` is removed from paths when byte-compiling modules. It is probably safe to use `--prefix` with `--root=/`, which should work with either setuptools or distutils-based `setup.py`’s but is kinda ugly. ### `pip` vs. `setup.py` [PEP 453](https://legacy.python.org/dev/peps/pep-0453/#recommendations-for- downstream-distributors) makes a recommendation to downstream distributors (us) that sdist tarballs should be installed with `pip` instead of by invoking `setup.py` directly. We do not do this because Apple’s Python distribution does not include pip, so we can’t assume that pip is available. We could do something clever to work around Apple’s piplessness but the value proposition is not yet clear. # Querying `brew` _In this document we will be using[jq](https://stedolan.github.io/jq/) to parse JSON, available from Homebrew using `brew install jq`._ ## Overview `brew` provides commands for getting common types of information out of the system. `brew list` shows installed formulae. `brew deps foo` shows the dependencies that `foo` needs. Additional commands, including external commands, can of course be written to provide more detailed information. There are a couple of disadvantages here. First, it requires writing Ruby against a possibly changing Homebrew codebase. There will be more code to touch during refactors, and Homebrew can’t guarantee that external commands will continue to work. Second, it requires designing the commands themselves, specifying input parameters and output formats. To enable users to do rich queries without the problems above, Homebrew provides the `brew info` command. ## `brew info --json` `brew info` can output JSON-formatted information about formulae. This JSON can then be parsed using your tools of choice. See more details in `brew info --help`. The default schema version is `v1`, which returns info about formulae; specify `--json=v2` to include both formulae and casks. Note that fields may be added to the schema as needed without incrementing the schema. Any significant breaking changes will cause a change to the schema version. The schema itself is not currently documented outside of the code in [`formula.rb`](https://github.com/Homebrew/brew/blob/2e6b6ab3a20da503ba2a22a37fdd6bd936d818ed/Library/Homebrew/formula.rb#L1922-L2017) that generates it. ## Examples _The top-level element of the JSON output is always an array, so the`map` operator is used to act on the data._ ### Pretty-print a single formula’s info brew info --json=v1 tig | jq . ### Installed formulae To show full JSON information about all installed formulae: brew info --json=v1 --all | jq "map(select(.installed != []))" You’ll note that processing all formulae can be slow; it’s quicker to let `brew` do this: brew info --json=v1 --installed ### Linked keg-only formulae Some formulae are marked as “keg-only”, meaning that installed files are not linked to the shared `bin`, `lib`, etc. directories, as doing so can cause conflicts. Such formulae can be forced to link to the shared directories, but doing so is not recommended (and will cause `brew doctor` to complain.) To find the names of linked keg-only formulae: brew info --json=v1 --installed | jq "map(select(.keg_only == true and .linked_keg != null) | .name)" ### Unlinked normal formulae To find the names of normal (not keg-only) formulae that are installed, but not linked to the shared directories: brew info --json=v1 --installed | jq "map(select(.keg_only == false and .linked_keg == null) | .name)" ## formulae.brew.sh [formulae.brew.sh](https://formulae.brew.sh) has a [documented JSON API](https://formulae.brew.sh/docs/api/) which provides access to the `brew info --json=v1` output without needing access to Homebrew. ## Concluding remarks By using the JSON output, queries can be made against Homebrew with less risk of being broken due to Homebrew code changes, and without needing to understand Homebrew’s Ruby internals. If the JSON output does not provide some information that it ought to, please submit a request, preferably with a patch to add the desired information. # Releases Since Homebrew 1.0.0 most Homebrew users (those who haven’t run a `dev-cmd` or set `HOMEBREW_DEVELOPER=1` which is ~99.9% based on analytics data) require tags on the [Homebrew/brew repository](https://github.com/homebrew/brew) in order to get new versions of Homebrew. There are a few steps in making a new Homebrew release: 1. Check the [Homebrew/brew pull requests](https://github.com/homebrew/brew/pulls), [issues](https://github.com/homebrew/brew/issues), [Homebrew/homebrew-core issues](https://github.com/homebrew/homebrew-core/issues) and [Homebrew/discussions (forum)](https://github.com/homebrew/discussions/discussions) to see if there is anything pressing that needs to be fixed or merged before the next release. If so, fix and merge these changes. 2. Ensure that no code changes have happened for at least a couple of hours (ideally 4 hours), at least one Homebrew/homebrew-core pull request CI job has completed successfully, checked the state of the Homebrew/brew `master` CI job (i.e. main jobs green or green after rerunning), and that you are confident there are no major regressions on the current `master`, branch. 3. Run `brew release` to create a new draft release. For major or minor version bumps, pass `--major` or `--minor`, respectively. 4. Publish the draft release on [GitHub](https://github.com/Homebrew/brew/releases). If this is a major or minor release (e.g. X.0.0 or X.Y.0) then there are a few more steps: 1. Before creating the tag you should delete any `odisabled` code, make any `odeprecated` code `odisabled`, uncomment any `# odeprecated` code and add any new `odeprecations` that are desired. Also delete any command argument definitions that pass `replacement: ...`. 2. Write up a release notes blog post to e.g. [brew.sh#319](https://github.com/Homebrew/brew.sh/pull/319). This should use the output from `brew release [--major|--minor]` as input but have the wording adjusted to be more human readable and explain not just what has changed but why. 3. When the release has shipped and the blog post has been merged, tweet the blog post as the [@MacHomebrew Twitter account](https://twitter.com/MacHomebrew) or tweet it yourself and retweet it with the @MacHomebrew Twitter account (credentials are in 1Password). 4. Consider whether to submit it to other sources e.g. Hacker News, Reddit. * Pros: gets a wider reach and user feedback * Cons: negative comments are common and people take this as a chance to complain about Homebrew (regardless of their usage) Please do not manually create a release based on older commits on the `master` branch. It’s very hard to judge whether these have been sufficiently tested by users or if they will cause negative side-effects with the current state of Homebrew/homebrew-core. If a new branch is needed ASAP but there are things on `master` that cannot be released yet (e.g. new deprecations and you want to make a patch release) then revert the relevant PRs, follow the process above and then revert the reverted PRs to reapply them on `master`. # Renaming a Formula Sometimes software and formulae need to be renamed. To rename a formula you need to: 1. Rename the formula file and its class to a new formula. The new name must meet all the usual rules of formula naming. Fix any test failures that may occur due to the stricter requirements for new formulae than existing formulae (i.e. `brew audit --online --new-formula` must pass for that formula). 2. Create a pull request to the corresponding tap deleting the old formula file, adding the new formula file, and adding it to `formula_renames.json` with a commit message like `newack: renamed from ack`. Use the canonical name (e.g. `ack` instead of `user/repo/ack`). A `formula_renames.json` example for a formula rename: { "ack": "newack" } # Homebrew Shell Completion Homebrew comes with completion definitions for the `brew` command. Some packages also provide completion definitions for their own programs. `zsh`, `bash` and `fish` are currently supported. You must manually configure your shell to enable its completion support. This is because the Homebrew-managed completions are stored under `HOMEBREW_PREFIX` which your system shell may not be aware of, and since it is difficult to automatically configure `bash` and `zsh` completions in a robust manner, the Homebrew installer does not do it for you. Shell completions for external Homebrew commands are not automatically installed. To opt-in to using completions for external commands (if provided), they need to be linked to `HOMEBREW_PREFIX` by running `brew completions link`. ## Configuring Completions in `bash` To make Homebrew’s completions available in `bash`, you must source the definitions as part of your shell’s startup. Add the following to your `~/.bash_profile` (or, if it doesn’t exist, `~/.profile`): if type brew &>/dev/null then HOMEBREW_PREFIX="$(brew --prefix)" if [[ -r "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" ]] then source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" else for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"* do [[ -r "${COMPLETION}" ]] && source "${COMPLETION}" done fi fi If you install the `bash-completion` formula, this will automatically source the completions’ initialisation script (so you do not need to follow the instructions in the formula’s caveats). If you are using Homebrew’s `bash` as your shell (i.e. `bash` >= v4) you should use the `bash-completion@2` formula instead. ## Configuring Completions in `zsh` To make Homebrew’s completions available in `zsh`, you must insert the Homebrew-managed `zsh/site-functions` path into your `FPATH` before initialising `zsh`’s completion facility. Add the following to your `~/.zshrc`: if type brew &>/dev/null then FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}" autoload -Uz compinit compinit fi This must be done before `compinit` is called. Note that if you are using Oh My Zsh, it will call `compinit` for you, so this must be done before you call `oh-my-zsh.sh`. This may be done by appending the following line to your `~/.zprofile` after Homebrew’s initialization, instead of modifying your `~/.zshrc` as above: FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}" You may also need to forcibly rebuild `zcompdump`: rm -f ~/.zcompdump; compinit Additionally, if you receive “zsh compinit: insecure directories” warnings when attempting to load these completions, you may need to run this: chmod -R go-w "$(brew --prefix)/share" ## Configuring Completions in `fish` No configuration is needed if you’re using Homebrew’s `fish`. Friendly! If your `fish` is from somewhere else, add the following to your `~/.config/fish/config.fish`: if test -d (brew --prefix)"/share/fish/completions" set -gx fish_complete_path $fish_complete_path (brew --prefix)/share/fish/completions end if test -d (brew --prefix)"/share/fish/vendor_completions.d" set -gx fish_complete_path $fish_complete_path (brew --prefix)/share/fish/vendor_completions.d end # Taps (Third-Party Repositories) The `brew tap` command adds more repositories to the list of formulae that Homebrew tracks, updates, and installs from. By default, `tap` assumes that the repositories come from GitHub, but the command isn’t limited to any one location. ## The `brew tap` command * `brew tap` without arguments lists all currently tapped repositories. For example: $ brew tap homebrew/cask homebrew/core petere/postgresql * `brew tap ` makes a clone of the repository at _https://github.com/ /homebrew-_ into `$(brew --repository)/Library/Taps`. After that, `brew` will be able to work with those formulae as if they were in Homebrew’s [homebrew/core](https://github.com/Homebrew/homebrew-core) canonical repository. You can install and uninstall them with `brew [un]install`, and the formulae are automatically updated when you run `brew update`. (See below for details about how `brew tap` handles the names of repositories.) * `brew tap ` makes a clone of the repository at _URL_. Unlike the one-argument version, _URL_ is not assumed to be GitHub, and it doesn’t have to be HTTP. Any location and any protocol that Git can handle is fine, although non-GitHub taps require running `brew tap --force-auto-update ` to enable automatic updating. * `brew tap --repair` migrates tapped formulae from a symlink-based to directory-based structure. (This should only need to be run once.) * `brew untap user/repo [user/repo user/repo ...]` removes the given taps. The repositories are deleted and `brew` will no longer be aware of their formulae. `brew untap` can handle multiple removals at once. ## Repository naming conventions and assumptions On GitHub, your repository must be named `homebrew-something` to use the one- argument form of `brew tap`. The prefix “homebrew-“ is not optional. (The two- argument form doesn’t have this limitation, but it forces you to give the full URL explicitly.) When you use `brew tap` on the command line, however, you can leave out the “homebrew-“ prefix in commands. That is, `brew tap username/foobar` can be used as a shortcut for the long version: `brew tap username/homebrew-foobar`. `brew` will automatically add back the “homebrew-“ prefix whenever it’s necessary. ## Formula with duplicate names If your tap contains a formula that is also present in [homebrew/core](https://github.com/Homebrew/homebrew-core), that’s fine, but you would need to specify its fully qualified name in the form `//` to install your version. Whenever a `brew install foo` command is issued, `brew` selects which formula to use by searching in the following order: * core formulae * other taps If you need a formula to be installed from a particular tap, you can use fully qualified names to refer to them. If you were to create a tap for an alternative `vim` formula, the behaviour would be: brew install vim # installs from homebrew/core brew install username/repo/vim # installs from your custom repository As a result, we recommend you give new names to customized formulae if you want to make them easier to install. Note that there is (intentionally) no way of replacing dependencies of core formulae with those from other taps. # Tips and Tricks ## Install previous versions of formulae Some formulae in `homebrew/core` are made available as [versioned formulae](versions) using a special naming format, e.g. `gcc@7`. If the version you’re looking for isn’t available, consider using `brew extract`. ## Quickly remove something from Homebrew’s prefix brew unlink This can be useful if a package can’t build against the version of something you have linked into Homebrew’s prefix. And of course, you can simply `brew link ` again afterwards! ## Pre-download a file for a formula Sometimes it’s faster to download a file via means other than the strategies that are available as part of Homebrew. For example, Erlang provides a torrent that’ll let you download at 4–5× compared to the normal HTTP method. Downloads are saved in the `downloads` subdirectory of Homebrew’s cache directory (as specified by `brew --cache`, e.g. `~/Library/Caches/Homebrew`) and renamed as `---`. The command `brew --cache --build-from-source ` will print the expected path of the cached download, so after downloading the file, you can run `mv the_tarball "$(brew --cache --build-from-source )"` to relocate it to the cache. You can also pre-cache the download by using the command `brew fetch ` which also displays the SHA-256 hash. This can be useful for updating formulae to new versions. ## Install stuff without the Xcode CLT brew sh # or: eval "$(brew --env)" gem install ronn # or c-programs This imports the `brew` environment into your existing shell; `gem` will pick up the environment variables and be able to build. As a bonus, `brew`’s automatically determined optimization flags are set. ## Install only a formula’s dependencies (not the formula) brew install --only-dependencies ## Use the interactive Homebrew shell $ brew irb ==> Interactive Homebrew Shell Example commands available with: `brew irb --examples` irb(main):001:0> Formulary.factory("ace").methods - Object.methods => [:install, :test, :test_defined?, :sbin, :pkgshare, :elisp, :frameworks, :kext_prefix, :any_version_installed?, :etc, :pkgetc, ... :on_macos, :on_linux, :debug?, :quiet?, :verbose?, :with_context] irb(main):002:0> ## Hide the beer mug emoji when finishing a build export HOMEBREW_NO_EMOJI=1 This sets the `HOMEBREW_NO_EMOJI` environment variable, causing Homebrew to hide all emoji. The beer emoji can also be replaced with other character(s): export HOMEBREW_INSTALL_BADGE="☕️ 🐸" ## Editor plugins ### Sublime Text * [Homebrew-formula-syntax](https://github.com/samueljohn/Homebrew-formula-syntax) can be installed with Package Control in Sublime Text 2/3, which adds highlighting for inline patches. ### Vim * [brew.vim](https://github.com/xu-cheng/brew.vim) adds highlighting to inline patches in Vim. ### Emacs * [homebrew-mode](https://github.com/dunn/homebrew-mode) provides syntax highlighting for inline patches as well as a number of helper functions for editing formula files. * [pcmpl-homebrew](https://github.com/hiddenlotus/pcmpl-homebrew) provides completion for emacs shell-mode and eshell-mode. ### Atom * [language-homebrew-formula](https://atom.io/packages/language-homebrew-formula) adds highlighting and diff support (with the [language-diff](https://atom.io/packages/language-diff) plugin). # Troubleshooting **Run`brew update` twice and `brew doctor` (and fix all the warnings) _before_ creating an issue!** This document will help you check for common issues and make sure your issue has not already been reported. ## Check for common issues * Read through the list of [Common Issues](common-issues). ## Check to see if the issue has been reported * Search the appropriate issue tracker to see if someone else has already reported the same issue: * [Homebrew/homebrew-core issue tracker](https://github.com/Homebrew/homebrew-core/issues) (formulae) * [Homebrew/homebrew-cask issue tracker](https://github.com/Homebrew/homebrew-cask/issues) (casks) * [Homebrew/brew issue tracker](https://github.com/Homebrew/brew/issues) (`brew` itself) * If the formula or cask that has failed to install is part of a non-Homebrew tap, then check that tap’s issue tracker instead. * Search the [Homebrew discussion forum](https://github.com/homebrew/discussions/discussions) or [Discourse archive](https://discourse.brew.sh/) to see if any discussions have started about the issue. ## Create an issue If your problem hasn’t been solved or reported, then create an issue: 1. Collect debugging information: * If you have a problem with installing a formula: run `brew gist-logs ` (where `` is the name of the formula) to upload the logs to a new [Gist](https://gist.github.com). * If your have a non-formula problem: collect the output of `brew config` and `brew doctor`. 2. Create a new issue on the issue tracker for [Homebrew/homebrew-core](https://github.com/Homebrew/homebrew-core/issues/new/choose), [Homebrew/homebrew-cask](https://github.com/Homebrew/homebrew-cask/issues/new/choose) or [Homebrew/brew](https://github.com/Homebrew/brew/issues/new/choose) and follow the instructions: * Give your issue a descriptive title which includes the formula name (if applicable) and the version of macOS or Linux you are using. For example, if a formula fails to build, title your issue “ failed to build on ”, where “” is the name of the formula that failed to build, and “” is the name and version of macOS or Linux you are using. * Include the URL provided by `brew gist-logs ` (if applicable) plus links to any additional Gists you may have created. * Include the output of `brew config` and `brew doctor`. # Type Checking With Sorbet The majority of the code in Homebrew is written in Ruby which is a dynamic language. To avail the benefits of static type checking, we have set up Sorbet in our codebase which provides the benefits of static type checking to dynamic languages like Ruby. The [Sorbet Documentation](https://sorbet.org/docs/overview) is a good place to get started if you want to dive deeper into Sorbet and it’s abilities. ## Sorbet in the Homebrew Codebase ### Inline Type Annotations To add type annotations to a class or module, we need to first extend it with the `T::Sig` module (read this as `Type::Signature`). This adds the `sig` method which is used to annotate method signatures. Here’s a simple example: class MyClass extend T::Sig sig { params(name: String).returns(String) } def my_method(name) "Hello, #{name}!" end end With `params`, we specify that we have a parameter `name` which must be a `String` and with `returns`, we specify that this method always returns a `String`. For more information on how to express more complex types, refer to the official documentation: * [Method Signatures](https://sorbet.org/docs/sigs) * [Class Types](https://sorbet.org/docs/class-types) * [Nilable Types](https://sorbet.org/docs/nilable-types) * [Union Types](https://sorbet.org/docs/union-types) ### Ruby Interface Files (`.rbi`) RBI files help Sorbet learn about constants, ancestors and methods defined in ways it doesn’t understand natively. We can also create a RBI file to help Sorbet understand dynamic definitions. Sometimes it is necessary to explicitly include the `Kernel` module in order for Sorbet to know that methods such as `puts` are available in a given context. This is mostly necessary for modules since they can be used in both `BasicObject`s (which don’t include `Kernel`) and `Object`s (which include `Kernel` by default). In this case, it is necessary to create an `.rbi` file ([example](https://github.com/Homebrew/brew/blob/61b79318ed089b5010501e2cbf163fd8e48e2dfc/Library/Homebrew/global.rbi)) since re-including the `Kernel` module in actual code can break things. Read more about RBI files [here](https://sorbet.org/docs/rbi). ### The [`Library/Homebrew/sorbet`](https://github.com/Homebrew/brew/tree/master/Library/Homebrew/sorbet) Directory * The `rbi` directory contains all Ruby Interface (`.rbi`) files auto-generated by running `brew typecheck --update`: * RBI files for all gems are generated using [Tapioca](https://github.com/Shopify/tapioca#tapioca). * Definitions for dynamic code (i.e. meta-programming) are generated using `srb rbi hidden-definitions`. * Definitions for missing constants are generated using `srb rbi todo`. * The `config` file is a newline-separated list of arguments to pass to `srb tc`, the same as if they’d been passed at the command-line. Arguments in the config file are always passed first, followed by arguments provided on the command-line. We use it to ignore Gem directories which we do not wish to type check. * Every Ruby file in the codebase has a magic `# typed: ` comment at the top, where `` is one of [Sorbet’s strictness levels](https://sorbet.org/docs/static#file-level-granularity-strictness-levels), usually `false`, `true` or `strict`. The `false` files only report errors related to the syntax, constant resolution and correctness of the method signatures, but no type errors. Our long-term goal is to move all `false` files to `true` and start reporting type errors on those files as well. Therefore, when adding new files, you should ideally mark it with `# typed: true` and work out any resulting type errors. ## Using `brew typecheck` When run without any arguments, `brew typecheck`, will run considering the strictness levels set in each of the individual Ruby files in the core Homebrew codebase. However, when it is run on a specific file or directory, more errors may show up since Sorbet cannot resolve constants defined outside the scope of the specified file. These problems can be solved with RBI files. Currently `brew typecheck` provides `--quiet`, `--file`, `--dir` and `--ignore` options but you can explore more options with `srb tc --help` and passing them with `srb tc`. ## Resolving Type Errors Sorbet reports type errors along with an error reference code, which can be used to look up more information on how to debug the error, or what causes the error in the [Sorbet Documentation](https://sorbet.org/docs/overview). Here is how to debug some common type errors: * Using `T.reveal_type`. In files which are `true` or higher, if we wrap a variable or method call in `T.reveal_type`, Sorbet will show us what type it thinks that variable has in the output of `srb tc`. This is particularly useful when writing [method signatures](https://sorbet.org/docs/sigs) and debugging. Make sure to remove this line from your code before committing your changes, since this is just a debugging tool. * One of the most frequent errors that we’ve encountered is: `7003: Method does not exist.` Since Ruby is a very dynamic language, methods can be defined in ways Sorbet cannot see statically. In such cases, check if the method exists at runtime, if not, then Sorbet has caught a future bug! But, it is also possible that even though a method exists at runtime, Sorbet cannot see it. In such cases, we use `.rbi` files. * Since Sorbet does not automatically assume that Kernel is to be included in Modules, we may encounter many errors while trying to use methods like `puts`, `ohai`, `odebug` et cetera. A simple workaround for this would be to add an extra `include Kernel` line in the respective RBI file. * The tips above are very generic and apply to lots of cases. For some common gotchas when using Sorbet, refer to the [Sorbet Error Reference](https://sorbet.org/docs/error-reference) and [FAQ](https://sorbet.org/docs/faq). # Updating Software in Homebrew Did you find something in Homebrew that wasn’t the latest version? You can help yourself and others by submitting a pull request to update the formula. First, check the pull requests in the Homebrew tap repositories to make sure a PR isn’t already open. If you’re submitting a [formula](formula- cookbook#homebrew-terminology), check [homebrew- core](https://github.com/Homebrew/homebrew-core/pulls). If you’re submitting a [cask](formula-cookbook#homebrew-terminology), check [homebrew- cask](https://github.com/Homebrew/homebrew-cask/pulls). You may also want to look through closed pull requests in the repositories, as sometimes packages run into problems preventing them from being updated and it’s better to be aware of any issues before putting significant effort into an update. The [How To Open a Homebrew Pull Request](how-to-open-a-homebrew-pull-request) documentation should explain most everything you need to know about the process of creating a PR for a version update. For simple updates, this typically involves changing the URL and SHA256 values. However, some updates require additional changes to the package. You can look back at previous pull requests to see how others have handled things in the past but be sure to look at a variety of PRs. Sometimes packages aren’t updated properly, so you may need to use your judgment to determine how to best proceed. Once you’ve created the pull request in the appropriate Homebrew repository your commit(s) will be tested on our continuous integration servers, showing a green check mark if everything passed or a red X if there were failures. Maintainers will review your pull request and provide feedback about any changes that need to be made before it can be merged. We appreciate your help in keeping Homebrew’s repositories up to date as new versions of software are released! # Versions [homebrew/core](https://github.com/homebrew/homebrew-core) supports multiple versions of formulae with a special naming format. For example, the formula for GCC 6 is named `gcc@6.rb` and begins with `class GccAT6 < Formula`. ## Acceptable versioned formulae Versioned formulae we include in [homebrew/core](https://github.com/homebrew/homebrew-core) must meet the following standards: * Versioned software should build on all Homebrew’s supported versions of macOS. * Versioned formulae should differ in major/minor (not patch) versions from the current stable release. This is because patch versions indicate bug or security updates, and we want to ensure you apply security updates. * Unstable versions (alpha, beta, development versions) are not acceptable for versioned (or unversioned) formulae. * Upstream should have a release branch for each formula version, and have an explicit policy of releasing security updates for each version when necessary. For example, [PHP 7.0 was not a supported version but PHP 7.2 was](https://php.net/supported-versions.php) in January 2020. By contrast, most software projects are structured to only release security updates for their latest versions, so their earlier versions are not eligible for versioning. * Versioned formulae should share a codebase with the main formula. If the project is split into a different repository, we recommend creating a new formula (`formula2` rather than `formula@2` or `formula@1`). * Formulae that depend on versioned formulae must not depend on the same formulae at two different versions twice in their recursive dependencies. For example, if you depend on `openssl@1.0` and `foo`, and `foo` depends on `openssl` then you must instead use `openssl`. * Versioned formulae should only be linkable at the same time as their non-versioned counterpart if the upstream project provides support for it, e.g. using suffixed binaries. If this is not possible, use `keg_only :versioned_formula` to allow users to have multiple versions installed at once. * A `keg_only :versioned_formula` should not `post_install` anything in the `HOMEBREW_PREFIX` that conflicts with or duplicates the main counterpart (or other versioned formulae). For example, a `node@6` formula should not install its `npm` into `HOMEBREW_PREFIX` like the `node` formula does. * Versioned formulae submitted should be expected to be used by a large number of people. If this ceases to be the case, they will be removed. We will aim not to remove those in the [top 3,000 `install_on_request` formulae](https://brew.sh/analytics/install-on-request/). * Versioned formulae should not have `resource`s that require security updates. For example, a `node@6` formula should not have an `npm` resource but instead rely on the `npm` provided by the upstream tarball. * Versioned formulae should be as similar as possible and sensible compared to the main formulae. Creating or updating a versioned formula should be a chance to ask questions of the main formula and vice versa, e.g. can some unused or useless options be removed or made default? * No more than five versions of a formula (including the main one) will be supported at any given time, regardless of usage. When removing formulae that violate this, we will aim to do so based on usage and support status rather than age. * Versioned formulae must be ABI stable for the lifetime of the version branch. Updates to the versioned formula must not introduce ABI incompatibilities or otherwise require dependents to be revision bumped. In practice, this means that their dependents should never need `revision` bumps to be rebuilt against newer versions. Version updates which violate this should be rejected and the formula be deprecated from that point onwards. Homebrew’s versions should not be used to “pin” formulae to your personal requirements. You should instead create your own [tap](how-to-create-and- maintain-a-tap) for formulae you or your organisation wish to control the versioning of, or those that do not meet the above standards. Software that has regular API or ABI breaking releases still needs to meet all the above requirements; that a `brew upgrade` has broken something for you is not an argument for us to add and maintain a formula for you. If there is a formula that currently exists in the Homebrew/homebrew-core repository or has existed in the past (i.e. was migrated or deleted), you can recover it for your own use with the `brew extract` command. This will copy the desired version of the formula into a custom tap. For example, if your project depends on `automake` 1.12 instead of the most recent version, you can obtain the `automake` formula at version 1.12 by running `brew extract automake / --version=1.12`. Formulae obtained this way may contain deprecated, disabled or removed Homebrew syntax (e.g. checksums may be `sha1` instead of `sha256`); the `brew extract` command does not edit or update formulae to meet current standards and style requirements. We may temporarily add versioned formulae for our own needs that do not meet these standards in [homebrew/core](https://github.com/homebrew/homebrew-core). The presence of a versioned formula there does not imply it will be maintained indefinitely or that we are willing to accept any more versions that do not meet the requirements above. # Xcode ## Supported Xcode versions Homebrew supports and recommends the latest Xcode and/or Command Line Tools available for your platform (see `OS::Mac::Xcode.latest_version` and `OS::Mac::CLT.latest_clang_version` in [`Library/Homebrew/os/mac/xcode.rb`](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/os/mac/xcode.rb)). ## Updating for new Xcode releases When a new Xcode release is made, the following things need to be updated: * In [`Library/Homebrew/os/mac/xcode.rb`](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/os/mac/xcode.rb) * `OS::Mac::Xcode.latest_version` * `OS::Mac::CLT.latest_clang_version` * `OS::Mac::Xcode.detect_version_from_clang_version`