From 034bf72235183c66c1a03850ad240c423d6b6a3f Mon Sep 17 00:00:00 2001 From: EricFromCanada Date: Tue, 19 Apr 2022 21:28:17 -0400 Subject: [PATCH 1/2] Contributors docs: adjust line breaks --- docs/Acceptable-Casks.md | 10 +- docs/Acceptable-Formulae.md | 57 ++++---- docs/Brew-Test-Bot.md | 17 +-- docs/How-To-Open-a-Homebrew-Pull-Request.md | 147 ++++++++++++-------- docs/How-to-Create-and-Maintain-a-Tap.md | 63 ++------- docs/Prose-Style-Guidelines.md | 3 +- docs/Rename-A-Formula.md | 3 +- docs/Typechecking.md | 100 +++---------- docs/Versions.md | 1 + 9 files changed, 161 insertions(+), 240 deletions(-) diff --git a/docs/Acceptable-Casks.md b/docs/Acceptable-Casks.md index 63d48c4778..73b0d603a1 100644 --- a/docs/Acceptable-Casks.md +++ b/docs/Acceptable-Casks.md @@ -1,8 +1,6 @@ # 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.md) and anyone can [start their own](Taps.md)! +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.md) and anyone can [start their own](How-to-Create-and-Maintain-a-Tap.md)! ## Finding a Home For Your Cask @@ -57,13 +55,11 @@ 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. +Font casks live in the [Homebrew/homebrew-cask-fonts](https://github.com/Homebrew/homebrew-cask-fonts) repository. See the fonts 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. +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 diff --git a/docs/Acceptable-Formulae.md b/docs/Acceptable-Formulae.md index 126c330054..80e47008a8 100644 --- a/docs/Acceptable-Formulae.md +++ b/docs/Acceptable-Formulae.md @@ -1,49 +1,43 @@ # 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.md) and anyone can start their -own! +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.md) 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.md#macos-requirements)) and on x86_64 [Linux](Linux-CI.md). -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. +The formula needs to build and pass tests on the latest 3 supported macOS versions ([x86_64 and Apple Silicon/ARM](Installation.md#macos-requirements)) and on x86_64 [Linux](Linux-CI.md). 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.md). ### 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). + +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). + +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.md) for them. +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.md) 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) @@ -52,40 +46,37 @@ The software in question must: * 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 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.md) if you have to! +Don’t forget Homebrew is all Git underneath! [Maintain your own tap](How-to-Create-and-Maintain-a-Tap.md) 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. +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). + +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. + +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. diff --git a/docs/Brew-Test-Bot.md b/docs/Brew-Test-Bot.md index e6db4d3485..da901c0c8f 100644 --- a/docs/Brew-Test-Bot.md +++ b/docs/Brew-Test-Bot.md @@ -5,21 +5,15 @@ image: https://brew.sh/assets/img/brewtestbot.png # 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). +`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. +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. +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: +For example, a job which has been queued but not yet completed will have a section in the pull request that looks like this: ![Triggered Pull Request](assets/img/docs/brew-test-bot-triggered-pr.png) @@ -37,6 +31,5 @@ A passed build looks like this: --- -On failed or passed builds you can click the "Details" link to view the result -in GitHub Actions. +On failed or passed builds you can click the "Details" link to view the result in GitHub Actions. diff --git a/docs/How-To-Open-a-Homebrew-Pull-Request.md b/docs/How-To-Open-a-Homebrew-Pull-Request.md index de77fa9275..ac65ca02c3 100644 --- a/docs/How-To-Open-a-Homebrew-Pull-Request.md +++ b/docs/How-To-Open-a-Homebrew-Pull-Request.md @@ -5,9 +5,11 @@ The following commands are used by Homebrew contributors to set up a fork of Hom 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 @@ -15,77 +17,99 @@ Depending on the change you want to make, you need to send the pull request to t ### 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. + * 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: - ```sh - cd "$(brew --repository)" - ``` + + ```sh + cd "$(brew --repository)" + ``` + 3. Add your pushable forked repository as a new remote: - ```sh - git remote add https://github.com//brew.git - ``` - * `` is your GitHub username, not your local machine username. + + ```sh + 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. + * 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: - ```sh - cd "$(brew --repository homebrew/core)" - ``` + + ```sh + cd "$(brew --repository homebrew/core)" + ``` + 3. Add your pushable forked repository as a new remote: - ```sh - git remote add https://github.com//homebrew-core.git - ``` - * `` is your GitHub username, not your local machine username. + + ```sh + 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. + * 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: - ```sh - cd "$(brew --repository homebrew/cask)" - ``` + + ```sh + cd "$(brew --repository homebrew/cask)" + ``` + 3. Add your pushable forked repository as a new remote: - ```sh - git remote add https://github.com//homebrew-cask.git - ``` - * `` is your GitHub username, not your local machine username. + + ```sh + 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: - ```sh - git checkout master - ``` + + ```sh + git checkout master + ``` + 2. Retrieve new changes to the `master` branch: - ```sh - brew update - ``` + + ```sh + brew update + ``` + 3. Create a new branch from the latest `master` branch: - ```sh - git checkout -b origin/master - ``` + + ```sh + 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.md) or [Cask Cookbook](Cask-Cookbook.md). - * 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. - ```sh - brew tests - brew install --build-from-source - brew test - brew audit --strict --online - ``` + * If there's a `bottle do` block in the formula, don't remove or change it; we'll update it when we merge 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 after your changed formula/cask has been installed. + + ```sh + brew tests + brew install --build-from-source + brew test + brew audit --strict --online + ``` + 6. [Make a separate commit](Formula-Cookbook.md#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`". + * 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: - ```sh - 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. + + ```sh + 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 from 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! @@ -96,7 +120,7 @@ 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. + * 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. @@ -104,20 +128,25 @@ To respond well to feedback: To make changes based on feedback: 1. Check out your branch again: - ```sh - git checkout - ``` + + ```sh + 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: - ```sh - 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: - ```sh - 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. + ```sh + 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: + + ```sh + 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 changes 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! diff --git a/docs/How-to-Create-and-Maintain-a-Tap.md b/docs/How-to-Create-and-Maintain-a-Tap.md index 60d87aa100..3f0731b006 100644 --- a/docs/How-to-Create-and-Maintain-a-Tap.md +++ b/docs/How-to-Create-and-Maintain-a-Tap.md @@ -1,29 +1,16 @@ # How to Create and Maintain a Tap -[Taps](Taps.md) 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. +[Taps](Taps.md) 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.md) for more information on repository naming. +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.md) for more information on repository naming. -The `brew tap-new` command can be used to create a new tap along with some -template files. +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. +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. +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 @@ -31,57 +18,35 @@ If your formulae have the same name as Homebrew/homebrew-core formulae they cann ### 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 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.md). +To install your tap without installing any formula at the same time, users can add it with the [`brew tap` command](Taps.md). 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. -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. +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. +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. +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. +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`. +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.md). +You can provide your tap users with custom `brew` commands by adding them in a `cmd` subdirectory. [Read more on external commands](External-Commands.md). -See [homebrew/aliases](https://github.com/Homebrew/homebrew-aliases) for an -example of a tap with external commands. +See [homebrew/aliases](https://github.com/Homebrew/homebrew-aliases) for an example of a tap with external commands. ## Official Vendor Taps diff --git a/docs/Prose-Style-Guidelines.md b/docs/Prose-Style-Guidelines.md index 5b2eabeec0..33c85fee9a 100644 --- a/docs/Prose-Style-Guidelines.md +++ b/docs/Prose-Style-Guidelines.md @@ -1,6 +1,7 @@ +# Prose Style Guidelines + -# 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. diff --git a/docs/Rename-A-Formula.md b/docs/Rename-A-Formula.md index b117f46116..0020851484 100644 --- a/docs/Rename-A-Formula.md +++ b/docs/Rename-A-Formula.md @@ -1,7 +1,6 @@ # Renaming a Formula -Sometimes software and formulae need to be renamed. To rename a formula -you need to: +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). diff --git a/docs/Typechecking.md b/docs/Typechecking.md index f93d126139..80ff2e0dae 100644 --- a/docs/Typechecking.md +++ b/docs/Typechecking.md @@ -1,20 +1,14 @@ # 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 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] is a good place -to get started if you want to dive deeper into Sorbet and it's abilities. +The [Sorbet Documentation] 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: +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: ```ruby class MyClass @@ -27,31 +21,20 @@ class MyClass 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`. +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: +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) +- [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. +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]) since re-including the -`Kernel` module in actual code can break things. +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]) since re-including the `Kernel` module in actual code can break things. Read more about RBI files [here](https://sorbet.org/docs/rbi). @@ -61,69 +44,32 @@ Read more about RBI files [here](https://sorbet.org/docs/rbi). [`Library/Homebrew/sorbet`]: https://github.com/Homebrew/brew/tree/master/Library/Homebrew/sorbet -- The `rbi` directory contains all Ruby Interface (`.rbi`) files - auto-generated by running `brew typecheck --update`: +- 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`. + - 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. +- 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], 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. +- Every Ruby file in the codebase has a magic `# typed: ` comment at the top, where `` is one of [Sorbet's 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. - [Sorbet's strictness levels]: https://sorbet.org/docs/static#file-level-granularity-strictness-levels +[Sorbet's strictness levels]: https://sorbet.org/docs/static#file-level-granularity-strictness-levels ## 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`. +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]. Here is how to debug some common 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]. 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. +- 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](#ruby-interface-files-rbi). +- 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](#ruby-interface-files-rbi). -- 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. +- 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). +- 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). [Sorbet Documentation]: https://sorbet.org/docs/overview diff --git a/docs/Versions.md b/docs/Versions.md index 6cd410704d..6375c0c48e 100644 --- a/docs/Versions.md +++ b/docs/Versions.md @@ -3,6 +3,7 @@ [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. From d615899ca9cf701ac5003350b33724bb1b7a8cf8 Mon Sep 17 00:00:00 2001 From: EricFromCanada Date: Wed, 19 Oct 2022 13:28:43 -0400 Subject: [PATCH 2/2] Contributors docs: content & formatting updates Update How-To-Open-a-Homebrew-Pull-Request.md Update Acceptable-Formulae.md Update Acceptable-Casks.md Update License-Guidelines.md Update Versions.md Update Versions.md Update Deprecating-Disabling-and-Removing-Formulae.md Update Node-for-Formula-Authors.md Update Python-for-Formula-Authors.md Update Brew-Livecheck.md Update Migrating-A-Formula-To-A-Tap.md Update Rename-A-Formula.md Update How-to-Create-and-Maintain-a-Tap.md Update Brew-Test-Bot.md Update Typechecking.md --- docs/Acceptable-Casks.md | 88 +++++++++---------- docs/Acceptable-Formulae.md | 26 +++--- docs/Brew-Livecheck.md | 10 +-- docs/Brew-Test-Bot.md | 2 +- ...ecating-Disabling-and-Removing-Formulae.md | 19 ++-- docs/How-To-Open-a-Homebrew-Pull-Request.md | 6 +- docs/How-to-Create-and-Maintain-a-Tap.md | 8 +- docs/License-Guidelines.md | 6 +- docs/Migrating-A-Formula-To-A-Tap.md | 10 +-- docs/Node-for-Formula-Authors.md | 20 ++--- docs/Python-for-Formula-Authors.md | 60 ++++++------- docs/README.md | 12 +-- docs/Rename-A-Formula.md | 4 +- docs/Typechecking.md | 20 ++--- docs/Versions.md | 22 +++-- 15 files changed, 158 insertions(+), 155 deletions(-) diff --git a/docs/Acceptable-Casks.md b/docs/Acceptable-Casks.md index 73b0d603a1..d8f0ec983e 100644 --- a/docs/Acceptable-Casks.md +++ b/docs/Acceptable-Casks.md @@ -4,7 +4,7 @@ Some casks should not go in [homebrew/cask](https://github.com/Homebrew/homebrew ## Finding a Home For Your Cask -We maintain separate Taps for different types of binaries. Our nomenclature is: +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. @@ -15,16 +15,16 @@ We maintain separate Taps for different types of binaries. Our nomenclature is: + **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. ++ **Vendorless**: A binary distributed via means other than 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 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 (Monterey and Ventura as of late 2022). -### But There Is No Stable Version! +#### 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. @@ -34,24 +34,24 @@ Alternative versions should be submitted to [Homebrew/homebrew-cask-versions](ht ### 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](https://docs.brew.sh/Cask-Cookbook#stanza-language). +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](https://docs.brew.sh/Cask-Cookbook#stanza-language). -### Trial and Freemium Versions +### 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. +Before submitting a trial, make sure it can be made into a full working version without needing 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 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: +Forks must have the vendor’s name as a prefix on the cask’s filename 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. +1. The original discontinued software recommends that fork. +2. 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. +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 +### Unofficial, Vendorless, and Walled builds -We do not accept these casks since they offer a higher-than-normal security risk. +We do not accept these casks since they involve a higher-than-normal security risk. ### Fonts @@ -63,33 +63,33 @@ Driver casks live in the [Homebrew/homebrew-cask-drivers](https://github.com/Hom ## 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](#homebrew-cask-is-not-a-discoverability-service). 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. +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](#homebrew-cask-is-not-a-discoverability-service). 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) +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. +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 along 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. +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.md). +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.md). -## Exceptions to the Notability Threshold +## Exceptions to the notability threshold Casks which do not reach a minimum notability threshold (see [Rejected Casks](#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. +1. A popular app that has its 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). +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’d be 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. +Note that 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. +From the inception of Homebrew Cask, various requests have fallen 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. +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 how 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. @@ -97,32 +97,32 @@ However, there is a difference between discoverability (finding new apps you did ## Rejected Casks -Before submitting a Cask to any of our repos, you must read [our documentation on acceptable Casks](#finding-a-home-for-your-cask) and perform a (at least quick) search to see if there were any previous attempts to introduce it. +Before submitting a cask to any of our repos, you must read our [documentation on acceptable casks](#finding-a-home-for-your-cask) 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: +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. ++ 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). ++ Cask is unreasonably difficult to maintain. Examples have included [Audacity](https://github.com/Homebrew/homebrew-cask/pull/27517) and [older Java development casks](https://github.com/Homebrew/homebrew-cask/issues/57387). ++ 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](https://docs.brew.sh/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: ++ 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 to the issue from your pull request so we can see the discussion and reasoning for rejection). ++ 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. ++ Cask 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](https://github.com/Homebrew/homebrew-cask/pull/9969) [submissions](https://github.com/Homebrew/homebrew-cask/pull/10606). ++ Cask is a duplicate. These submissions mostly occur when the [token reference](https://docs.brew.sh/Cask-Cookbook#token-reference) was not followed. ++ Cask has a download URL that is both behind a login/registration form and from a host that differs from the homepage, meaning users can’t easily verify its authenticity. ++ App is unmaintained, i.e. no releases in the last year, or [explicitly discontinued](https://github.com/Homebrew/homebrew-cask/pull/22699). ++ App 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). ++ App has no information on its 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`](https://docs.brew.sh/Cask-Cookbook#pkg-allow_untrusted). ++ App requires [SIP to be disabled](https://github.com/Homebrew/homebrew-cask/pull/41890) to be installed and/or used. ++ App installer is a `pkg` that requires [`allow_untrusted: true`](https://docs.brew.sh/Cask-Cookbook#pkg-allow_untrusted). -Common reasons to reject a Cask from the main repo: +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](#finding-a-home-for-your-cask)” to see where it belongs. ++ Cask was submitted to the wrong repo. When drafting a cask, consult [Finding a Home For Your Cask](#finding-a-home-for-your-cask) to see where it belongs. -## No cask is guaranteed to be accepted +### 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. +Follow the guidelines above and your submission has a great chance of being accepted. But remember that 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. diff --git a/docs/Acceptable-Formulae.md b/docs/Acceptable-Formulae.md index 80e47008a8..8d5cf45334 100644 --- a/docs/Acceptable-Formulae.md +++ b/docs/Acceptable-Formulae.md @@ -1,16 +1,18 @@ # 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.md) and anyone can start their own! +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.md) and anyone can [start their own](How-to-Create-and-Maintain-a-Tap.md)! -### Supported platforms in `homebrew/core` +## Requirements for `homebrew/core` + +### Supported platforms The formula needs to build and pass tests on the latest 3 supported macOS versions ([x86_64 and Apple Silicon/ARM](Installation.md#macos-requirements)) and on x86_64 [Linux](Linux-CI.md). 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` +### Duplicates of system packages 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` +### Versioned formulae We now accept versioned formulae as long as they [meet the requirements](Versions.md). @@ -20,15 +22,13 @@ Software that can upgrade itself does not integrate well with Homebrew's own upg ### 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 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). +Our policy is that formulae in the core tap ([homebrew/core](https://github.com/Homebrew/homebrew-core)) must be open-source with a [Debian Free Software Guidelines license](https://wiki.debian.org/DFSGLicenses) and either built from source or producing cross-platform binaries (e.g. Java, Mono). Binary-only formulae should go in [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. +Additionally, core formulae must also not depend on casks or any other proprietary software. This includes automatic installation of casks at runtime. ### Stable versions @@ -41,8 +41,8 @@ We don’t accept software without a tagged version because they regularly break 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 known * be used * have a homepage @@ -70,13 +70,13 @@ Clang is the default C/C++ compiler on macOS (and has been for a long time). Sof 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 +### 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 +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 +## 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. diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 89bbf46a06..63856f5d79 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,6 +1,6 @@ # `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. +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) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior @@ -13,21 +13,21 @@ When livecheck isn't given instructions for how to check for upstream versions, 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/resource. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). +This can be accomplished by adding a `livecheck` block to the formula/cask/resource. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck). ## 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. -1. **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. +1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url` to see if it provides 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. 1. **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](#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 `strategy` when it's necessary**. For example, if livecheck is already using the `Git` strategy 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. +* **Only use the `GithubLatest` strategy when it's necessary and correct**. GitHub rate-limits requests so 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 diff --git a/docs/Brew-Test-Bot.md b/docs/Brew-Test-Bot.md index da901c0c8f..e42e89892f 100644 --- a/docs/Brew-Test-Bot.md +++ b/docs/Brew-Test-Bot.md @@ -7,7 +7,7 @@ image: https://brew.sh/assets/img/brewtestbot.png `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. +It comprises three Mac Pros hosting virtual machines, several M1 Mac minis and some cloud Ubuntu instances 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 diff --git a/docs/Deprecating-Disabling-and-Removing-Formulae.md b/docs/Deprecating-Disabling-and-Removing-Formulae.md index b7828385fd..8ce61a93a9 100644 --- a/docs/Deprecating-Disabling-and-Removing-Formulae.md +++ b/docs/Deprecating-Disabling-and-Removing-Formulae.md @@ -1,20 +1,20 @@ -# Deprecating, Disabling, and Removing Formulae +# 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. +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: +These general rules 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. +- 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. +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 continue to be maintained by the Homebrew maintainers so they 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. @@ -30,7 +30,7 @@ To deprecate a formula, add a `deprecate!` call. This call should include a depr 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 `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 when 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](#deprecate-and-disable-reasons) section below for more details about the `because` parameter. @@ -49,7 +49,7 @@ The most common reasons for disabling a formula are: 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** +**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: @@ -76,9 +76,10 @@ There are two ways to indicate the reason. The preferred way is to use a pre-exi - `: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) +- `:unsupported`: Homebrew's compilation of the software is not supported by the upstream developers (e.g. upstream only supports macOS versions older than 10.15) - `:deprecated_upstream`: the project is deprecated upstream - `:versioned_formula`: the formula is a versioned formula +- `:checksum_mismatch`: the checksum of the source for the formula's current version has changed since bottles were built These reasons can be specified by their symbols (the comments show the message that will be displayed to users): @@ -92,7 +93,7 @@ deprecate! date: "2020-01-01", because: :deprecated_upstream 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 !`. +If these pre-existing reasons do not fit, a custom reason can be specified. Such 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: diff --git a/docs/How-To-Open-a-Homebrew-Pull-Request.md b/docs/How-To-Open-a-Homebrew-Pull-Request.md index ac65ca02c3..86c8c0f734 100644 --- a/docs/How-To-Open-a-Homebrew-Pull-Request.md +++ b/docs/How-To-Open-a-Homebrew-Pull-Request.md @@ -1,8 +1,8 @@ -# How To Open a Homebrew Pull Request +# 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. +The type of change you want to make influences which of Homebrew's main repositories you'll need to send your pull request to. If you want to submit a change to Homebrew's core code (the `brew` implementation), you should open a pull request on [Homebrew/brew](https://github.com/Homebrew/brew). If you want to submit a change for a formula, you should open a pull request on the [homebrew/core](https://github.com/Homebrew/homebrew-core) tap, while 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 @@ -70,7 +70,7 @@ Depending on the change you want to make, you need to send the pull request to t ## 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: +To make changes on a new branch and submit it for review, create a GitHub pull request with the following steps: 1. Check out the `master` branch: diff --git a/docs/How-to-Create-and-Maintain-a-Tap.md b/docs/How-to-Create-and-Maintain-a-Tap.md index 3f0731b006..9fc6e8798a 100644 --- a/docs/How-to-Create-and-Maintain-a-Tap.md +++ b/docs/How-to-Create-and-Maintain-a-Tap.md @@ -8,15 +8,15 @@ A tap is usually a Git repository available online, but you can use anything as 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. +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 the 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 +### 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). +If a formula in your tap has the same name as a Homebrew/homebrew-core formula 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 a more full-featured `nginx` formula. This will allow both `nginx` and `nginx-full` to be installed at the same time (assuming one is [`keg_only`](https://rubydoc.brew.sh/Formula#keg_only-class_method) or the linked files do not clash). -### Installing +## 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. diff --git a/docs/License-Guidelines.md b/docs/License-Guidelines.md index 2b626b31cf..14b8d414f2 100644 --- a/docs/License-Guidelines.md +++ b/docs/License-Guidelines.md @@ -1,6 +1,6 @@ # 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). +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) into `homebrew/core`. ## Specifying a License @@ -77,7 +77,7 @@ license any_of: [ 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. +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: @@ -109,7 +109,7 @@ license any_of: ["MIT", "0BSD"] 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` +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`: ```bash export HOMEBREW_FORBIDDEN_LICENSES="GPL-2.0-only LGPL-2.1-or-later" diff --git a/docs/Migrating-A-Formula-To-A-Tap.md b/docs/Migrating-A-Formula-To-A-Tap.md index cc50990777..08c54d7d42 100644 --- a/docs/Migrating-A-Formula-To-A-Tap.md +++ b/docs/Migrating-A-Formula-To-A-Tap.md @@ -1,11 +1,11 @@ -# Migrating A Formula To A Tap +# 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`. +1. Create a pull request on 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 compared to existing formulae (e.g. `brew audit --strict` must pass for that formula). +2. Create a pull request on the original tap deleting the formula file and adding 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! +Congratulations, you've moved a formula to another 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. +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. diff --git a/docs/Node-for-Formula-Authors.md b/docs/Node-for-Formula-Authors.md index df9cfec310..028ac1be4e 100644 --- a/docs/Node-for-Formula-Authors.md +++ b/docs/Node-for-Formula-Authors.md @@ -14,13 +14,11 @@ 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). +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 -``` + 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. @@ -32,7 +30,7 @@ Node modules which are compatible with the latest Node version should declare a 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`). +If your formula requires being executed with an older Node version you should use one of its versioned formulae (e.g. `node@12`). ### Special requirements for native addons @@ -42,7 +40,7 @@ If your Node module is a native addon or has a native addon somewhere in its dep 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). +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 (being invoked with an ABI-incompatible Node version). ## Installation @@ -50,8 +48,8 @@ Node modules should be installed to `libexec`. This prevents the Node modules fr 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`](#installing-global-style-modules-with-std_npm_install_args-to-libexec) (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`](#installing-module-dependencies-locally-with-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)) +* formulae for standard Node modules compatible with npm's global module format which should use [`std_npm_install_args`](#installing-global-style-modules-with-std_npm_install_args-to-libexec) (like [`apollo-cli`](https://github.com/Homebrew/homebrew-core/blob/790c4298124d49823e5b9286d07519c1c1a9f773/Formula/apollo-cli.rb) or [`webpack`](https://github.com/Homebrew/homebrew-core/blob/6bb687199709b9cfed362efc9581e0ef24917acd/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`](#installing-module-dependencies-locally-with-local_npm_install_args) (like [`emscripten`](https://github.com/Homebrew/homebrew-core/blob/140d42bd9ada53cfd921abf964796dbf5bac1c3b/Formula/emscripten.rb) or [`grunt-cli`](https://github.com/Homebrew/homebrew-core/blob/0ab5d8e18f1dea2c4c57407a17f4aa4b8e985d76/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. @@ -69,7 +67,7 @@ In your formula's `install` method, simply `cd` to the top level of your Node mo 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: +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 are not symlinked into Homebrew's prefix. To make sure these are installed, we need to symlink all executables to `bin` with: ```ruby bin.install_symlink Dir["#{libexec}/bin/*"] @@ -77,13 +75,13 @@ 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: +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` to invoke `npm install` with `Language::Node.local_npm_install_args` like: ```ruby 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.md). +This will install all of your Node modules' dependencies to your local build path. You can now continue with your build steps and handle the installation into the Homebrew prefix on your own, following the [general Homebrew formula instructions](Formula-Cookbook.md). ## Example diff --git a/docs/Python-for-Formula-Authors.md b/docs/Python-for-Formula-Authors.md index 4fded0d11a..59674dd58a 100644 --- a/docs/Python-for-Formula-Authors.md +++ b/docs/Python-for-Formula-Authors.md @@ -10,25 +10,25 @@ Bindings are a special case of libraries that allow Python code to interact with 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 should unconditionally bundle all 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 +### Python declarations for applications 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 +### Installing applications -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. +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.md#we-dont-like-install-scripts-that-download-unversioned-things). +All the Python module dependencies of the application (and their dependencies, recursively) should be declared as [`resource`](https://rubydoc.brew.sh/Formula#resource-class_method)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.md#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: +If using `brew update-python-resources` doesn't work, you can use [homebrew-pypi-poet](https://github.com/tdsmith/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: ```sh # Use a temporary directory for the virtual environment @@ -75,7 +75,7 @@ def install end ``` -### Example +### Example formula Installing a formula with dependencies will look like this: @@ -86,13 +86,13 @@ class Foo < Formula url "..." resource "six" do - url "https://pypi.python.org/packages/source/s/six/six-1.9.0.tar.gz" - sha256 "e24052411fc4fbd1f672635537c3fc2330d9481b18c0317695b46259512c91d5" + url "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz" + sha256 "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926" end resource "parsedatetime" do - url "https://pypi.python.org/packages/source/p/parsedatetime/parsedatetime-1.4.tar.gz" - sha256 "09bfcd8f3c239c75e77b3ff05d782ab2c1aed0892f250ce2adf948d4308fe9dc" + url "https://files.pythonhosted.org/packages/a8/20/cb587f6672dbe585d101f590c3871d16e7aec5a576a1694997a3777312ac/parsedatetime-2.6.tar.gz" + sha256 "4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455" end def install @@ -121,7 +121,7 @@ To add bindings for Python 3, please add `depends_on "python@3.x"` to work with 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 +### Dependencies for bindings Bindings should follow the same advice for Python module dependencies as libraries; see below for more. @@ -147,39 +147,39 @@ Sometimes we have to edit a `Makefile` on-the-fly to use our prefix for the Pyth ## Libraries -### Python declarations +### Python declarations for libraries 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/). +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 not, 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 +### Installing libraries -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. +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 +### Dependencies for libraries -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. +Library dependencies 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 +### 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. +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. +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`, it 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. +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. +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: +For when a formula needs to interact with `setup.py` instead of calling `pip`, Homebrew provides the 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: ```ruby system Formula["python@3.x"].opt_bin/"python3", *Language::Python.setup_install_args(prefix) @@ -189,7 +189,7 @@ 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`. +`--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 using Distutils to perform the install instead of Setuptools' `easy_install`. `easy_install` does a few things that we need to avoid: @@ -197,17 +197,17 @@ where `prefix` is the destination prefix (usually `libexec` or `prefix`). * 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". +Setuptools requires that SVEM be 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 name 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`. +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. +`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 with 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. +`--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. +It is probably safe to use `--prefix` with `--root=/`, which should work with either Setuptools- or Distutils-based `setup.py`'s, but it's kinda ugly. ### `pip` vs. `setup.py` diff --git a/docs/README.md b/docs/README.md index af11b6e8f5..16e77fb730 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ - [External Commands](External-Commands.md) - [Ruby Gems, Python Eggs and Perl Modules](Gems,-Eggs-and-Perl-Modules.md) - [Python](Homebrew-and-Python.md) -- [How To Build Software Outside Homebrew With Homebrew `keg_only` dependencies](How-to-Build-Software-Outside-Homebrew-with-Homebrew-keg-only-Dependencies.md) +- [How to Build Software Outside Homebrew with Homebrew `keg_only` Dependencies](How-to-Build-Software-Outside-Homebrew-with-Homebrew-keg-only-Dependencies.md) - [Xcode](Xcode.md) - [Creating a Homebrew Issue](Creating-a-Homebrew-Issue.md) @@ -35,21 +35,21 @@ ## Contributors -- [How To Open A Pull Request (and get it merged)](How-To-Open-a-Homebrew-Pull-Request.md) +- [How to Open a Pull Request (and get it merged)](How-To-Open-a-Homebrew-Pull-Request.md) - [Formula Cookbook](Formula-Cookbook.md) - [Cask Cookbook](Cask-Cookbook.md) - [Acceptable Formulae](Acceptable-Formulae.md) - [Acceptable Casks](Acceptable-Casks.md) - [License Guidelines](License-Guidelines.md) - [Formulae Versions](Versions.md) -- [Deprecating, Disabling, and Removing Formulae](Deprecating-Disabling-and-Removing-Formulae.md) +- [Deprecating, Disabling and Removing Formulae](Deprecating-Disabling-and-Removing-Formulae.md) - [Node for Formula Authors](Node-for-Formula-Authors.md) - [Python for Formula Authors](Python-for-Formula-Authors.md) - [`brew livecheck`](Brew-Livecheck.md) -- [Migrating A Formula To A Tap](Migrating-A-Formula-To-A-Tap.md) -- [Rename A Formula](Rename-A-Formula.md) +- [Migrating a Formula to a Tap](Migrating-A-Formula-To-A-Tap.md) +- [Renaming a Formula](Rename-A-Formula.md) - [Building Against Non-Homebrew Dependencies](Building-Against-Non-Homebrew-Dependencies.md) -- [How To Create (And Maintain) A Tap](How-to-Create-and-Maintain-a-Tap.md) +- [How to Create and Maintain a Tap](How-to-Create-and-Maintain-a-Tap.md) - [Brew Test Bot](Brew-Test-Bot.md) - [Diagram Guidelines](Diagram-Guidelines.md) - [Prose Style Guidelines](Prose-Style-Guidelines.md) diff --git a/docs/Rename-A-Formula.md b/docs/Rename-A-Formula.md index 0020851484..1bdc2806fc 100644 --- a/docs/Rename-A-Formula.md +++ b/docs/Rename-A-Formula.md @@ -2,9 +2,9 @@ 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). +1. Rename the formula file and its class to a new formula name. 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 compared to existing formulae (e.g. `brew audit --strict` 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`). +2. Create a pull request on 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: diff --git a/docs/Typechecking.md b/docs/Typechecking.md index 80ff2e0dae..e2f0a408a8 100644 --- a/docs/Typechecking.md +++ b/docs/Typechecking.md @@ -2,13 +2,13 @@ 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] is a good place to get started if you want to dive deeper into Sorbet and it's abilities. +The [Sorbet Documentation] is a good place to get started if you want to dive deeper into Sorbet and its 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: +To add type annotations to a class or module, we 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: ```ruby class MyClass @@ -21,7 +21,7 @@ class MyClass 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`. +With `params` we specify that there is 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: @@ -32,12 +32,10 @@ For more information on how to express more complex types, refer to the official ### 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. +[RBI files](https://sorbet.org/docs/rbi) help Sorbet learn about constants, ancestors and methods defined in ways it doesn’t understand natively. We can also create an 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]) since re-including the `Kernel` module in actual code can break things. -Read more about RBI files [here](https://sorbet.org/docs/rbi). - [example]: https://github.com/Homebrew/brew/blob/61b79318ed089b5010501e2cbf163fd8e48e2dfc/Library/Homebrew/global.rbi ### The [`Library/Homebrew/sorbet`] Directory @@ -50,7 +48,7 @@ Read more about RBI files [here](https://sorbet.org/docs/rbi). - 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. +- The `config` file is a newline-separated list of arguments to pass to `srb tc`, the same as if they’d been passed on 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], 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. @@ -58,17 +56,17 @@ Read more about RBI files [here](https://sorbet.org/docs/rbi). ## 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`. +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 pass 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]. 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. +- Using `T.reveal_type`: in files which are `true` or higher, by wrapping 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](#ruby-interface-files-rbi). +- 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](#ruby-interface-files-rbi). -- 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. +- 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` etc. A simple workaround for this is 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). diff --git a/docs/Versions.md b/docs/Versions.md index 6375c0c48e..0d8a28380f 100644 --- a/docs/Versions.md +++ b/docs/Versions.md @@ -1,27 +1,33 @@ -# Versions +# Formulae 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`. +[homebrew/core](https://github.com/homebrew/homebrew-core) supports multiple versions of formulae by using 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 software should build on all of 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. +* 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. by 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/). +* Submitted versioned formulae 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. +* 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.md) 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. +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.md) 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. +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: + +```sh +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.