Skip to content

Commit

Permalink
Merge pull request Homebrew#16606 from Homebrew/deprecation-disable-f…
Browse files Browse the repository at this point in the history
…orks-versions-docs

Update Acceptable/Deprecating/Forks/Versions docs
  • Loading branch information
MikeMcQuaid committed Feb 14, 2024
2 parents dda1785 + 7220d94 commit 9475258
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 18 deletions.
13 changes: 12 additions & 1 deletion docs/Acceptable-Casks.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ We maintain separate taps for different types of binaries. Our nomenclature is:

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 `homebrew/cask` repository. When stable versions become available, only those will be accepted as subsequent updates.

Expand Down Expand Up @@ -83,6 +83,17 @@ Casks which do not reach a minimum notability threshold (see [Rejected Casks](#r

Note that none of these exceptions is a guarantee for inclusion, but examples of situations where we may take a second look.

## Not a fork (usually)

We will not add new casks using forks unless at least one of the following is true:

* the fork has been designated the official successor in the original source repository (e.g. in the README) or in a publicly verifiable way by the original author (e.g. in an issue or pull request comment)
* the fork has been used as the replacement by at least two other major distributions (e.g. Debian, Fedora, Arch, Gentoo, not smaller Linux distributions that are not widely used)

The fork should still meet all the other acceptable casks requirements (including those of e.g. popularity and self-submission).

An alternative to the fork replacing the original cask is a new cask. For example, if `MikeMcQuaid` forked `google-chrome` and it was very popular: a `mikemcquaid-google-chrome` cask might make sense.

## Homebrew Cask is not a discoverability service

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.
Expand Down
11 changes: 11 additions & 0 deletions docs/Acceptable-Formulae.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ We now accept stuff that comes with macOS as long as it uses `keg_only :provided

We now accept versioned formulae as long as they [meet the requirements](Versions.md).

### Not a fork (usually)

We will not add new formulae using forks unless at least one of the following is true:

* the fork has been designated the official successor in the original source repository (e.g. in the README) or in a publicly verifiable way by the original author (e.g. in an issue or pull request comment)
* the fork has been used as the replacement by at least two other major distributions (e.g. Debian, Fedora, Arch, Gentoo, not smaller Linux distributions that are not widely used)

The fork must still meet all the other acceptable formulae requirements (including those of e.g. popularity and self-submission).

An alternative to the fork replacing the original formula is a new formula. For example, if `MikeMcQuaid` forked `curl` and it was very popular: a `curl-mikemcquaid` formula might make sense.

### We don’t like tools that upgrade themselves

Software that can upgrade itself does not integrate well with Homebrew formulae's own upgrade functionality. The self-update functionality should be disabled (while minimising complication to the formula). It's fine (and well-supported) for Casks.
Expand Down
100 changes: 100 additions & 0 deletions docs/Deprecating-Disabling-and-Removing-Casks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Deprecating, Disabling and Removing Casks

There are many reasons why casks 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

These general rules of thumb can be followed:

- `deprecate!` should be used for casks that _should_ no longer be used.
- `disable!` should be used for casks that _cannot_ be used.
- Casks that are no longer acceptable in `homebrew/cask` or have been disabled for over a year _should_ be removed.

## Deprecation

If a user attempts to install a deprecated cask, they will be shown a warning message but the install will proceed.

A cask should be deprecated to indicate to users that the cask should not be used and will be disabled in the future. Deprecated casks should continue to be maintained by the Homebrew maintainers if they continue to be installable. If this is not possible, they should be immediately disabled.

The most common reasons for deprecation are when the upstream project is deprecated, unmaintained or archived.

Casks should only be deprecated if at least one of the following are true:

- the software installed by the cask cannot be run on any of our supported macOS versions
- the cask has outstanding CVEs
- the cask has [zero installs in the last 90 days](https://formulae.brew.sh/analytics/cask-install/90d/)
- the software installed by the cask has been discontinued upstream

To deprecate a cask, add a `deprecate!` call. This call should include a deprecation date in the ISO 8601 format and a deprecation reason:

```ruby
deprecate! date: "YYYY-MM-DD", because: :reason
```

The `date` parameter should be set to the date that the deprecation period should begin, which is usually today's date. If the `date` parameter is set to a date in the future, the cask 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. Do not backdate the `date` parameter as it causes confusion for users and maintainers.

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.

## Disabling

If a user attempts to install a disabled cask, they will be shown an error message and the install will fail.

A cask should be disabled to indicate to users that the cask cannot be used and will be removed in the future. Disabled cask are those that could not be installed successfully any longer.

The most common reasons for disabling a cask are:

- it cannot be installed on any of our supported macOS versions
- it has been deprecated for a long time
- the upstream URL has been removed

Popular casks (e.g. have more than 300 [analytics installs in the last 90 days](https://formulae.brew.sh/analytics/cask-install/90d/)) should not be disabled without a deprecation period of at least six months unless they cannot be installed on all macOS versions and issue is unable be fixed (e.g. download URL no longer works and a mirror cannot be sourced).

Unpopular casks (e.g. have fewer than 300 [analytics installs in the last 90 days](https://formulae.brew.sh/analytics/cask-install/90d/)) can be disabled immediately for any of the reasons above.
They can be manually removed three months after their disable date.

To disable a cask, add a `disable!` call. This call should include a deprecation date (in the ISO 8601 format) and a deprecation reason:

```ruby
disable! date: "YYYY-MM-DD", because: :reason
```

The `date` parameter should be set to the date that the reason for disabling came into effect. If there is no clear date but the cask needs to be disabled, use today's date. If the `date` parameter is set to a date in the future, the cask will be deprecated until that date (on which the cask will become disabled).

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.

## Removal

A cask should be removed if it does not meet our criteria for [acceptable casks](Acceptable-Casks.md) or has been disabled for over a year.

**Note: disabled casks in `homebrew/cask` will be automatically removed one year after their disable date.**

## Deprecate and Disable Reasons

When a cask is deprecated or disabled, a reason explaining the action must be provided.

There are two ways to indicate the reason. The preferred way is to use a pre-existing symbol to indicate the reason. The available symbols are listed below and can be found in the [`DeprecateDisable` module](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/deprecate_disable.rb):

- `:discontinued`: the cask is discontinued upstream

These reasons can be specified by their symbols (the comments show the message that will be displayed to users):

```ruby
# Warning: <cask> has been deprecated because it is discontinued upstream!
deprecate! date: "2020-01-01", because: :discontinued
```

If these pre-existing reasons do not fit, a custom reason can be specified. Such reasons should be written to fit into the sentence `<cask> has been deprecated/disabled because it <reason>!`.

A well-worded example of a custom reason would be:

```ruby
# Warning: <cask> has been deprecated because it has unresolved CVEs!
deprecate! date: "2020-01-01", because: "has unresolved CVEs"
```

A poorly-worded example of a custom reason would be:

```ruby
# Error: <cask> has been disabled because it broken!
disable! date: "2020-01-01", because: "broken"
```
37 changes: 21 additions & 16 deletions docs/Deprecating-Disabling-and-Removing-Formulae.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,22 @@ A formula should be deprecated to indicate to users that the formula should not

The most common reasons for deprecation are when the upstream project is deprecated, unmaintained, or archived.

Formulae with dependents may be deprecated only if at least one of the following are true:
Formulae should only be deprecated if at least one of the following are true:

- its dependents are all deprecated
- the formula does not build on any of our supported macOS versions and on Linux
- the formula has outstanding CVEs
- the formula has [zero installs in the last 90 days](https://formulae.brew.sh/analytics/install/90d/)
- the software installed by the formula has been discontinued or abandoned upstream

Formulae with dependents should not be deprecated until or when all dependents are also deprecated.

To deprecate a formula, add a `deprecate!` call. This call should include a deprecation date (in the ISO 8601 format) and a deprecation reason:

```ruby
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 when the project or version will stop being supported.
The `date` parameter should be set to the date that the deprecation period should begin, which is usually 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. Do not backdate the `date` parameter as it causes confusion for users and maintainers.

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.

Expand All @@ -42,16 +45,16 @@ A formula should be disabled to indicate to users that the formula cannot be use

The most common reasons for disabling a formula are:

- it cannot be built from source (meaning no bottles can be built)
- it cannot be built from source on all supported OS versions (meaning no new bottles can be built)
- it has been deprecated for a long time
- the upstream repository has been removed
- the project has no license

Formulae should not be disabled without a deprecation period of at least three months unless the circumstances are exceptional (e.g. the formula does not build on any supported macOS version or Linux). Popular formulae should have longer deprecation periods. The popularity of a formula should be based on our analytics data.
Popular formulae (e.g. have more than 1000 [analytics installs in the last 90 days](https://formulae.brew.sh/analytics/install/90d/)) should not be disabled without a deprecation period of at least six months even if e.g. they do not build from source and do not have a license.

**Note: disabled formulae in `homebrew/core` will be automatically removed one year after their disable date.**
Unpopular formulae (e.g. have fewer than 1000 [analytics installs in the last 90 days](https://formulae.brew.sh/analytics/install/90d/)) can be disabled immediately for any of the reasons above e.g. they cannot be built from source on any supported macOS version or Linux.
They can be manually removed three months 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:
To disable a formula, add a `disable!` call. This call should include a deprecation date in the ISO 8601 format and a deprecation reason:

```ruby
disable! date: "YYYY-MM-DD", because: :reason
Expand All @@ -65,21 +68,23 @@ The `because` parameter can be a preset reason (using a symbol) or a custom reas

A formula should be removed if it does not meet our criteria for [acceptable formulae](Acceptable-Formulae.md) or [versioned formulae](Versions.md), has a non-open-source license, or has been disabled for over a year.

**Note: disabled formulae in `homebrew/core` will be automatically removed one year after their disable date.**

## Deprecate and Disable Reasons

When a formula is deprecated or disabled, a reason explaining the action must be provided.

There are two ways to indicate the reason. The preferred way is to use a pre-existing symbol to indicate the reason. The available symbols are listed below and can be found in the [`DeprecateDisable` module](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/deprecate_disable.rb):

- `:does_not_build`: the formula cannot be built from source
- `:no_license`: the formula does not have a license
- `:repo_archived`: the upstream repository has been archived
- `:repo_removed`: the upstream repository has been removed
- `:unmaintained`: the project appears to be abandoned
- `:does_not_build`: the formula cannot be built from source on any supported macOS version or Linux.
- `:no_license`: we cannot identify a license for the formula
- `:repo_archived`: the upstream repository has been archived and no replacement is pointed to that we can use
- `:repo_removed`: the upstream repository has been removed and no replacement is mentioned on the homepage that we can use
- `:unmaintained`: the project appears to be abandoned i.e. it has had no commits for at least a year and has critical bugs or CVE that have been reported and gone resolved longer. Note: some software is "done"; a lack of activity does not imply a need for removal.
- `: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
- `:deprecated_upstream`: the project is deprecated upstream and no replacement is pointed to that we can use
- `:versioned_formula`: the formula is a versioned formula and no longer [meets the requirements](Versions.md).
- `:checksum_mismatch`: the checksum of the source for the formula's current version has changed since bottles were built and we cannot find a reputable source or statement justifying this

These reasons can be specified by their symbols (the comments show the message that will be displayed to users):

Expand Down
2 changes: 1 addition & 1 deletion docs/Versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Versioned formulae we include in [homebrew/core](https://github.com/homebrew/hom
* 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.
* No more than five versions of a formula (including the main one) will be supported at any given time, unless they are popular (e.g. have over 1000 [analytics 90 days installs](https://formulae.brew.sh/analytics/install/90d/) of usage). When removing formulae that violate this, we will aim to do so based on usage and support status rather than age.
* Versioned formulae must be ABI-stable for the lifetime of the version branch. Updates to the versioned formula must not introduce ABI incompatibilities or otherwise require dependents to be revision bumped. In practice, this means that their dependents should never need `revision` bumps to be rebuilt against newer versions. Version updates which violate this should be rejected and the formula be deprecated from that point onwards.

Homebrew's versions should not be used to "pin" formulae to your personal requirements. You should instead [create your own tap](How-to-Create-and-Maintain-a-Tap.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.
Expand Down

0 comments on commit 9475258

Please sign in to comment.